On Thu, Dec 9, 2010 at 4:19 PM, Mike Edwards
<[email protected]> wrote:
> 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.
>

I'd guess that the Tuscany JMS binding __does__ already work under
OSGi, but the problem is how do you configure an OSGi container to
provided a JNDI environment.

We use ActiveMQ for the testcases but the JMS binding uses just
standard JavaEE APIs and JNDI lookups so it works with any JavaEE JNDI
environment. Along with standalone ActiveMQ Tuscany also works with
Tomcat, WebSphere, JBoss, Glassfish, - or any JavaEE compliant
AppServer - and it uses the AppServer's defined JMS resources. We have
users using that capability and its function i think we should try
hard to keep working.

That code in (1) would fail if ActiveMQ isn't available so it would
need to handle the class not being found or else be in a separate
module. The Tuscany JMSResourceFactory is one of the JMS binding plug
points so it could easily be a new separate module for an ActiveMQ
specific JMSResourceFactory.

I do wonder though if there are more standard ways to do JNDI in OSGi,
other enterprise OSGi things must already have a way of doing it. I
don't know anything about it but a google turns up:
http://incubator.apache.org/aries/jndiproject.html

   ...ant

Reply via email to