[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [xmlblaster-devel] Global/Property problems



Peter Antman wrote:
(Sorry if this is posted two times, the first was sent from the wrong
mailing adress)

Hi,

Hi as well,

I am having problems updating the JBoss support in XmlBlaster. One of
the problems has to do with the way Global works. Therefore this rather
long mail.

I think the property handling is broken in XmlBlaster: it is to complex,
and it is very hard to really get a consistent and forseeable result by
using the Property/util.Global/engine.Global API. There are to many
automatic ways the environment gets rewritten, reloaded or changed.
Unfortunately it is so complex that it is even hard to describe what's
broken.

Therefore an example.

Say we want to run XmlBlaster as an embedded service in JBoss
(XmlBlasterService) with a CorbaDriver. Here are some more
prerequisites:

* Full control over which properties are loaded ( no automagic loading
of properties file).

Could be handled by callback interface of the loading class, we would need to enhance http://www.xmlblaster.org/xmlBlaster/doc/requirements/util.property.html http://www.xmlblaster.org/xmlBlaster/doc/requirements/util.property.env.html For example passing a listener like this to Global: I_PropertyRetriever() { Properties getProperies() { // Somehow pass your own properties } }

But i think after cleaning up the code (see below) it should
not be necessary.


* System properties may not override xmlBlaster.properties since the xml parser will be broken then.

System properties are weakest in xmlBlaster. They can be switched off in jutils:

  public Property(String fileName, boolean scanSystemProperties,
                  String[] args, boolean replaceVariables)

we could forward this possibility to Global if necessary.


* Jacorb will not be able to load its propertyfile the normal way since it uses the system classloader to find it, which almost never works in embedded environments (XmlBlaster has these types of problems to).

JacORB is configured with the jacorb.properties file.
The xmlBlaster/lib/xmlBlaster.jar file contains a copy of this template file which is loaded by JacORB via the CLASSPATH and configures JacORB accordingly.


If you remove jacorb.properties form xmlBlaster.jar you can put a jacorb.properties file into your home directory which you can use configure JacORB behavior. Note that if there is a file in xmlBlaster.jar this has precedence.

Setting a JacORB property on command line as System.property has precedence over any jacorb.properties setting (e.g. java -DORBInitRef.NameService=file:///tmp/ns.ior ...).


* Jacorb can not handle ORBInitRef.type of properties wich has first
been loader from a property file and then converter to an args array,
i.e -ORBInitRef.NameService args is not valid as a an args to the
ORB.init method.

I think ORB.init() wins always but i would need to investigate this and update http://www.xmlblaster.org/xmlBlaster/doc/requirements/protocol.corba.JacORB.html


What we really want to do the is this:

1. Create an empty Global wich reads in System properties.
2. Manually load the property file.
These two steps are one in org.jutils.init.Property

3. Manually load jacorb.properties and populate Global.
The jacorb.properties is in the scope of the CORBA protocol plugin
only, we can't explicitly load it with Global.

4. Fill in any component specific configs.



This will however NOT work. Lets follow the logic.

First we look at all the possible ways of creating/getting a Global and
populate it.First of all though:

Global contains two different properties:
1. A Property object, which contains all properties, also the ones from
the "Environment", such as System.properties
2. An args array wich logically only should contains the "commandline"
arguments.
So heres how to create/get one.
Global.new() -> args will be null, and property be populated from
xmlBlaster.properties (looked up through Property.findPath),
System.properties (,no user props).

In util.Global: this.args is now removed, it makes no sense.


Global.new(Properties props) and Global.new(String[] args) -> property is populated from xmlBlaster.properties (looked up through Property.findPath), System.properties, user props from properties or args. Global.args will also be set with props or args and Property will be populated one more time with these.

These are identical:

   public Global(Properties props) {
      this(Property.propsToArgs(props)); // call String[] args ctor
   }



Global.new(String[] args, boolean loadPropFile, boolean checkInstanc) ->
same as above, except that its possible to tell Property not to load the
propertyfile.

Global.new(Global glob) -> references to glob

Was deprecated and is removed now.


Global.instance() -> either the first global created or Global.new(), no way to tell when calling.

Global() is just a convenience for Global(null, true, true)


Global.getClone(String[] args) -> will take all properties in old Global and create a new Global with these as argument. This effectively means that the new Global will have the old Globals properties both in its args and property object. With one exception: if its called with a non null, non empty args, the new Globals args will be set with theses, overwriting all the properties that was set. These will also be added to the properties of the new Global.

args and Properties are identical (just a different representation) and in this case the given args are added to the new Global. This is just a convenience method so that you don't have to call

  glob.init(args)

for the new Global yourself.



Global.clone() -> same as above, except that no new args or properties
are set. .i.e all properties that the old Global contained will not be
both in Global.args and its Property.

This effectively means that:
1. Its impossible to create a Global with only "properties" and no args.
2. The only way to have other properties than args is to populate it
after it was created.
3. There is NO way of creating a new Global from a old Global that
really makes it look the same, i.e the args is the same in both and
properties is the same, since all properties in the old will be args in
the new. 4. There is no way to let System.properties override properties loaded
after
Global was created.

If you need this, just use

   glob.init(Properties props);


So, lets look at how to do the example.

// Create a global without automatic propertyfile expansion.
Global glob = new Global( null, false, false);
Properties p = loadPropFile();
g.getProperty().addArgs2Props( p );
Properties j = loadJacorbProps();
g.getProperty().addArgs2Props( j );

We now have a global, where properties was loaded from another, system
controllable properties file, and we have properties loaded for jacorb.
No Global.args is set at al.
This is the best we can do. Its not perfect, since it makes it
impossible to override properties in the loaded property file through
System.properties, but since we do not have full control over that
environment its probably the best thing to do.




Well, what happens when EmbeddedXmlBlaster is started? Depending on
which classloader strategy is use either new Main(glob) or
Main.init(glob)will be called. What happened there?

In the first case a engine.Global is created: new engine.Global(glob).
In the second case a engine.Global is created, but like this: new
engine.Global(glob, true).

In both cases this results i a call to util.Global (which is the
superclass):
super(Property.propsToArgs(utilGlob.getProperty().getProperties()),
true, false); // the boolean propertyOnly is not used at all in the
latter case


WOAW, what happened here?
1. The property file is loaded once again!
2. All properties in utilGlob is also set as args in the new Glob
3. Any args from utilGlob is forgotten (but are there anyway as part of
all the properties).

This looks buggy indeed, it should be fixed now (see cvs).



I must say I think this is a very confusing behaviour. My feeling is
that there are far to many roads on how the properties are set (and they
are set several times in some cases).

But, lets continue with the example. We have loaded the
jacorb.properties file, wich was in our util.Global instance. This file
must by definition contain entries like these to handle full
configuration of Jacorb:

 ORBInitRef.ImplementationRepository=http://www.x.y.z/~user/ImR_Ref

The problem with the Jacorb used in the current XmlBlaster is that
jacorb
does not accept these types of properties as commandline arguments. The
args part of ORB.init may therefore NOT contain entries looking like
this:

  -ORBInitRef.ImplementationRepository http://www.x.y.z/~user/ImR_Ref

Either they must look like this:
  -ORBInitRef.ImplementationRepository=http://www.x.y.z/~user/ImR_Ref

   or
  -ORBInitRef ImplementationRepository=http://www.x.y.z/~user/ImR_Ref

Both types are impossible to represent in a Properties object (with one
exception: if only one ORBInitRef variable is used at all, in wich case
it could be written like this in the propertyfile:
ORBInitRef=NameService=corbaloc:iiop:localhost:7608/StandardNS/NameServer-POA/_root)
Since XmlBlaster effectively instantiates the orb like this:


org.omg.CORBA.ORB.init(glob.getArgs(),properties);

We have changed it to

  org.omg.CORBA.ORB.init(null, glob.getProperty().getProperties());

after checking Jacorbs org.jacorb.ORB.java:
Jacorb ignores args totally except the args setting "-ORBInitRef"
(which has precedence over properties).


This means that the orb is given an argument that may previously have lived in a properties object, which will result in the following error:

java.lang.StringIndexOutOfBoundsException: String index out of range: -1
stackTrace=java.lang.StringIndexOutOfBoundsException: String index out
of range: -1
        at java.lang.String.substring(String.java:1480)
        at org.jacorb.orb.ORB.set_parameters(ORB.java:1324)
        at org.omg.CORBA.ORB.init(ORB.java:337)
        at
org.xmlBlaster.protocol.corba.OrbInstanceFactory.createOrbInstance(OrbInstanceFactory.java:183)
        at
org.xmlBlaster.protocol.corba.CorbaDriver.init(CorbaDriver.java:165)

This is a Jacorb bug when the key and the value are not separated by a '='.


Yes, this was a rather long mail and the example problem described here is possible to solve by manipulating the jacorb.properties file. The reason I wrote this long mail anyhow is that I think that the handling of the Environment/Properties in XmlBlaster is confusing. I have done three integrations round with XmlBlaster, and during all three I have been forced to relearn how the properties are handled and have had large problems handling all side effects that are built into this.

We try to improve, thanks for such a detailed report!


I have no good solution; perhaps this mail could be the start of such a discussion. But at least one thing out to be done emediately: when cloning or creating a new Global with global as argument no property file loading should be done and the objects should look the same regarding args and properties.

This should be fixed now, see the current cvs.

best regards,

Michele and Marcel

--
http://www.xmlBlaster.org