Folks,
In the current codebase, binding.jms does not run under OSGi.
I want to fix this since I believe that it is important that all Tuscany code should be able to run
under OSGi.
The problem area is the binding-jms-runtime module and the method that it uses to load the
particular JMS provider.
The code involved is in the JMSResourceFactoryImpl class in
org.apache.tuscany.sca.binding.jms.provider - in the getInitialContext() method.
The code here does a load of a JNDI InitialContext:
// Load the JNDI InitialContext (will load the InitialContextFactory,
if present)
context = new InitialContext(props);
The (well known) problem with this under OSGi is that the InitialContext code tries to load an
InitialContextFactory class, named as a text string in a properties file, using loadClass method of
the ThreadContextClassLoader.
Under OSGi, this breaks since the TCCL does not typically have access rights to the bundle
containing the InitialContextFactory class.
For ActiveMQ (which is our default JMS provider today), the class involved is
ActiveMQInitialContextFactory which is in the activemq-core bundle/jar.
The existing Tuscany code has no "smart fix" for this situation - unlike META-INF/services style
classes, for which we do have a solution.
So to get this to work under OSGi, I propose the following:
1. Change the code in getInitialContext to the following:
ClassLoader tccl = ClassLoaderContext.setContextClassLoader(
JMSResourceFactoryImpl.class.getClassLoader(),
ActiveMQInitialContextFactory.class.getClassLoader(),
Thread.currentThread().getContextClassLoader()
);
try {
// Load the JNDI InitialContext (will load the
InitialContextFactory, if present)
context = new InitialContext(props);
} finally
// Restore the TCCL if we changed it
if( tccl != null )
Thread.currentThread().setContextClassLoader(tccl);
} // end try
this sets up the TCCL to enable it to load the ActiveMQInitialContextFactory
class
2. Add a POM dependency on activemq-core
- this can be made a "provided" dependency
3. Add a package dependency to the MANIFEST.MF for package
org.apache.activemq.jndi
- this can be made an optional dependency
org.apache.activemq.jndi;resolution:=optional,
This change has the effect of making the jms runtime package depend on ActiveMQ - we may want to
provide alternative jms runtime packages for other JMS providers at some later point, but I think we
need to get the code working under OSGi right away and so this approach is a good first step.
Yours, Mike.