Hi,

Maybe you can try this:

ServiceDiscovery.getServiceDeclaration("/" 
+contextFactoryClassName+".class").loadClass(contextFactoryClassName).getClassLoader();

getServiceDeclaration() finds the OSGi entry for the class file.

Thanks,
Raymond
________________________________________________________________ 
Raymond Feng
[email protected]
Apache Tuscany PMC member and committer: tuscany.apache.org
Co-author of Tuscany SCA In Action book: www.tuscanyinaction.com
Personal Web Site: www.enjoyjava.com
________________________________________________________________

On Dec 9, 2010, at 8:19 AM, Mike Edwards 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.

Reply via email to