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.