I've run into some issues with the standard XML libraries.  Calls like this:

TransformerFactory.newInstance()

are particularly unsuited to the OSGI environment.  The above call, for 
example, attempts to identify the name of the class to instantiate from a 
number of locations.  These are:

1) The value of a system property
2) The presence of some properties file in java.home
3) The presence of a resource under META-INF/services accessed through the 
context ClassLoader

Once the name of the class is found, the context ClassLoader is used to 
instantiate it.

The first two locations are especially nasty in an OSGI environment, as it can 
mean that the factory looks up the name of the class from a location completely 
unrelated to the class space in which the class will be instantiated.  The 
third location can be made to work - as the context ClassLoader can be set to 
the current bundle ClassLoader prior to calling, and frameworks (like spring 
dm) often set it this way too.

The product that I develop has recently moved to using OSGI for class isolation 
and modularity, and it's a great fit.  One of the advantages we see in using 
OSGI is the ability to isolate your application from its environment.  This is 
particularly important when you don't have control over the deployment 
environment e.g. the application is to be installed on a client site where the 
java or servlet container environment managed by another IT department.

OSGI has definitely delivered benefits to us in keeping our code isolated from 
the environment but patterns such as the TransformerFactory.newInstance() 
situation still give us problems.  In some situations the web container or even 
a sibling application sets the associated system property, and our application 
is then broken because the named class is not visible to us.

In our own code we use direct constructor of the xml library we wish to 
instantiate to prevent this happening.  However sometimes libraries we include 
new the newInstance() method (spring dm is the main offender here - the spring 
beans parser), and we can't change them.

One thing we have done to standardise the xml libraries used inside our 
application is to remove all the javax.xml.* packages from the system packages 
list, and to include apache xmlcommons, resolver, and xerces bundles found in 
the springsource repository e.g:

http://www.springsource.com/repository/app/bundle/version/detail?name=com.springsource.org.apache.xmlcommons&version=1.3.4

This standardises the xml apis across all jvms, but the newInstance() problem 
remains.

I was thinking about modifying the newInstance() methods in the xmlcommons 
bundle to be correct for an OSGI environment.  In the first instance I was 
simply going to change the search order so that the META-INF/services step 
comes first, as this can be controlled in our bundles.   However I was 
wondering how I could go about making a full OSGI implementation of this 
system.  It could do something like:

1) Return an instance of a TransformerFactory service if one exists (I guess 
the highest version available if multiple)
2) Use the META-INF/services location of the context ClassLoader
3) Read the OSGI framework properties (rather than system properties)

So, some questions:

Has anyone else had this problem and overcome it without requiring changes to 
the application environment?
Would an OSGI version of xmlcommons be useful to anyone else?
How should it be designed? Is the above search order sensible?  Anything else 
that would make sense within an OSGI runtime?

Regards

Lindsay Smith


_______________________________________________
OSGi Developer Mail List
[email protected]
https://mail.osgi.org/mailman/listinfo/osgi-dev

Reply via email to