In general, this is a pretty well known issue. Well enough known that OSGi 
has a special section of their spec to cover it. 
Well, at least for the Parser cases .... I don't recall seeing anything 
for Transformer, but I think the issues and principles
are the same. So, if you didn't know that, you might find interesting the 
'XML Parser Service Specification' section of the 
Compendium Specification 
http://www.osgi.org/download/r4v42/r4.cmpn.pdf 

Also, you might study through bugs and code in Equinox related to this 
(again, I know of parser cases .. would be
similar for Transformer, I suspect, if Transformer was spec'd). Such as 
see 
https://bugs.eclipse.org/bugs/show_bug.cgi?id=285505 
At its heart, equinox provides the context classloader solution (again, 
for parsers). 
The bugzilla entry also provides links to some other xml commons bugs that 
are interesting from an OSGi point of view, 
though again, not directly related to solving your problem. 

Also be aware that Eclipse Orbit offers some "OSGi'ed" versions of 
xmlcommons libraries, but do not modify 
code or provide a service. Such as see 
http://download.eclipse.org/tools/orbit/downloads/drops/R20100519200754/
I'm not saying these would solve your problem ... but, if you create your 
own bundles, beware of "conflicts" with 
other bundles out in the wild. 

I am no OSGi expert, but I'd think you could provide a service to create 
your new instance, any way you want, 
and that'd be preferable to changing someone else's "newInstance" code ... 

but then application code would have to know to use your service (not sure 
if you were ruling that out, or not). 

I'm not sure the problem can be solved, without application code knowing 
how/which service to call, but 
best of luck. 







From:   Lindsay Smith <[email protected]>
To:     "[email protected]" <[email protected]>
Date:   10/11/2010 04:33 PM
Subject:        [osgi-dev] XML libraries - TransformerFactory.newInstance 
and     friends
Sent by:        [email protected]



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
_______________________________________________
OSGi Developer Mail List
[email protected]
https://mail.osgi.org/mailman/listinfo/osgi-dev

Reply via email to