Folks,
After rather more work than I would have hoped for, I have finally got Web Services running on the
2.0 codebase.
There are interesting challenges, some of which have solutions which are not (yet) in a form which
can be adopted generally in the codebase. I'll try to describe them here, step by step.
Most of the challenges turn out to be classloading issues - unsurprising given the move to OSGi in
2.0. Some of the problems are a bit thorny and some of them involve the handling of 3rd party code.
1) XML Parsing
Parts of the codebase involve the use of XML Parsing, which may either be DOM parsing or SAX
parsing. It turns out that some of our code depends explicitly on the Xerces DOM parser
implementation and some depends on the Woodstox SAX parser implementation.
This turns out to be complex, especially on Java 1.6.0. The basic problem is that there is an API
layer for each type of parser, which in turn loads the parser implementation code. The API layer
discovers the available parser implementations through Factory declarations in the JAR
/META-INF/services directory.
So far so good, except that in JDK 1.6.0 BOTH of the API layers (for DOM Parsing and for SAX
parsing) are actually in the base JDK itself. When this happens, the API layer and the Parser
implementation unfortunately end up in different OSGi bundles - the Core bundle and the Equinox
library bundle (in practice). And so, when the API layer finds and tries to load the Parser code -
the Parser class is not found as it is not marked as a dependency of the API code.
I used two alternative strategies to solve this.
For Xerces, I found only one dependency on this in binding-ws-axis2 - and I removed it. These days,
XML DOM Parsing is present in the core JDK and there is no need to specify some other parser package.
For Woodstox, there are a number of our modules depending on this and instead of trying to eliminate
this, I used the technique of putting the wstx-asl-3.2.4.jar into the jre\lib\endorsed directory of
my JDK1.6.0 installation. This then treats the Woodstok Parser as an extension of the Core - and in
OSGi terms puts the Parser code into the same bundle as the rest of Core.
2) Incorrect labelling of OSGi Dependencies
There were a number of Manifest files that stated a dependence on javax.xml.namespace with
version="1.0.0". I have no idea where this version number came from - but it is not good. This
package is in Core in both JDK 1.5.x and JDK 1.6.0 and it is *NOT* at 1.0.0 level.
Simply removing the version number entirely solves this problem.
3) Cross-Bundle Class Loading Problems
It turns out that some of the 3rd Party libraries that we use involve code that loads classes from
outside the library, but where there is no explicit dependency of the 3rd party code on the code
package(s) from which the classes are loaded. Typically, this involves 3rd party code that supplies
library extension APIs where the NAME of an extensio class belonging to the CALLER is passed in
through the API, but the classes are instantiated by the code within the API layer.
There are 2 main cases of this:
1) Axis2 - the axis2-kernel-1.4.1 module. This has an API which is used to load a class from our
binding-ws-axis2 module.
2) Axiom - the axiom-api module loads classes from the axiom-dom and from the
axiomn-impl modules
In both these cases, there is no explicit dependency of the loading module on the module from which
the class(es) are loaded - and in reality, neither should there be, since the other module is in a
sense a "user" of the loading module.
I decided that the way to fix this was to patch the MANIFEST files of the bundles concerned to use
the Eclipse Buddy technology. This means that:
a) The bundle doing the loading of these "foreign" classes is marked with
"Eclipse-BuddyPolicy: dependent"
- which says that the module has some "buddy" modules from which some classes
will be loaded
b) The bundle(s) providing the loaded classes are marked with:
"Eclipse-RegisterBuddy: xxxxxxxxxxx"
- where xxxxxxxxxxxx is the symbolic name of the bundle from a) - and this
indicates that this
bundle provides classes to the first bundle.
One problem with this approach is that it only works for Equinox and I don't think it is available
for other OSGi implementations such as Felix.
We need to think harder about this problem, but something like the BuddyPolicy solution is needed -
and we need to coax the 3rd Party providers to add this to their bundle manifests.
Yours, Mike.