On Mar 14, 2007, at 8:15 AM, Jarek Gawor wrote:

I'm working on the SAAJ integration in Geronimo. I have the following
idea on how to integrate it and I would applicate any comments,
suggestions, better solutions, etc.

We have three different SAAJ implementations to work with: Axis1,
Axis2, and Sun. And we can't really just use one as Axis1/Axis2 expect
their own implementations. Also, please keep in mind that within the
same module we can have both JAX-RPC and JAX-WS web services.
Now, in G code in certain places we know exactly what sort of SAAJ
implementation should be used. For example, if I'm invoking a Axis2
service, it should be using Axis2 SAAJ implementation. Or if I'm
calling a JAX-RPC service (using service-ref) Axis1 SAAJ
implementation should be used, and so on. So the idea is this:

First, in such places that we know what implementation should be used,
set the SAAJ implementation preference explicitly. For example:

SAAJUniverse universe = new SAAJUniverse(SAAJUniverse.Axis1);
universe.set();
try {
 // invoke the web service
} finally {
 universe.unset();
}

The .set() method would set some thread local variable with the SAAJ
implementation preference.

If a webservice can call another webservice locally (using the same thread), you will need to keep the original thread local value and reset it on the way out.

Second, we would provide our own implementations of the different SAAJ
Factory classes. These factory classes would just check that thread
local preference variable and return the appropriate factory instance.
Or if no preference is set, default to Sun's implementation.

Do all the SAAJ implementations implement the same spec API version? If not you will not be able to switch implementations like this.

Just to clarify, the user is not expected to do the SAAJUniverse
set/unset bit. Only the web service container implementations or
service-ref builders would do that (i.e. the idea is to make it
transparent to the user as much as possible).

Also, if a call is made within some SAAJ universe but then it is
handled by some thread pool later on, things might break. So this
solution is definitely not foolproof but hopefully good enough.

It should work as long as you reset the thread local in a finally block as you have above.

Another idea I've had was to create a new context classloader (when
set() is called) instead of the thread local solution. That new
context classloader would first load a specific jar file for the SAAJ
implementation (the jar file would just contain SAAJ configuration
files) and delegate everything else to the existing context
classloader. That way, since the right configuration files would
appear first in the classloader, it would force the right SAAJ
implementation to be used (the SAAJ factory classes first check the
context classloader for the configuration files).

I don't see how this could work as the resource data would likely be cached by Java code, so when you attempt switch to another SAAJ implementation the Java code won't notice the CL switch.

Thoughts?

I was worried that we would have to force all WS stacks to a common SAAJ implementation, but this may just work.

-dain

Reply via email to