tomee-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Jean-Baptiste Onofré ...@nanthrax.net>
Subject Re: injection of one EJB in another in OSGi
Date Mon, 27 Feb 2012 12:27:35 GMT
Hi guys,

A ThreadContextClassLoader could also fix the issue, but it requires 
some change in the code.

Regards
JB

On 02/27/2012 01:24 PM, Romain Manni-Bucau wrote:
> Hi,
>
> in tomcat we use this classloader as paretn of the webapp classloader so
> everything is fine.
>
> In OSGi i think a kind of multipleclassloader can fix this issue: try to
> load the class in openejb application classloader before the bundle
> classloader itself.
>
> - Romain
>
>
> 2012/2/27 Borislav Kapukaranov<b.kapukaranov@gmail.com>
>
>> Hey folks,
>>
>> I'm trying to get OpenEJB running on Equinox and it is going fairly well so
>> far. :-)
>> Until I got stucked in the following issue - I have a WebApp that has two
>> local EJBs (*X* and *Y*) and a Servlet. *X* has annotated field with type
>> *Y
>> *. The Servlet has annotated fields for both EJBs.
>> My web container is GeminiWeb and with the help of my own ObjectFactory it
>> handles the Servlet binding and the injection of the EJB's in the Servlet
>> just fine.
>> However there is one more injection that is needed - *Y* proxy into *X*.
>> This is where I got trouble.
>>
>> I'm using a bundle that triggers the deployment of the WebApp as an OpenEJB
>> module by plugging into Tomcat's mechanics. My bundle calls
>> *org.apache.openejb.assembler.DeployerEjb.deploy(String
>> location)* - this method does the heavy lifting for me by processing the
>> annotations and binds all EJB's in OpenEjb's internal JNDI so all is fine
>> here.
>> When a bean is injected somewhere, a proxy is created for this bean.
>> In this code snippet from *LocalBeanProxyGeneratorImpl* we can see how a
>> proxy is generated:
>>
>> private Class createProxy(*Class<?>  clsToProxy*, String proxyName,
>> *ClassLoader
>> cl*) {
>>     String clsName = proxyName.replaceAll("\\.", "/");
>>     try {
>>         return *cl.loadClass(proxyName);*
>>     } catch (Exception e) {}
>>     try {
>>         byte[] proxyBytes = generateProxy(clsToProxy, clsName);
>>         return (Class<?>) defineClass.invoke(unsafe, proxyName, proxyBytes,
>> 0, proxyBytes.length, *clsToProxy.getClassLoader()*,
>> clsToProxy.getProtectionDomain());
>>     } catch (Exception e) {
>>         throw new InternalError(e.toString());
>>     }
>> }
>>
>> I've highlighted what is important for the OSGi case
>> *- clsToProxy* is the bean's class - this is loaded and defined by the
>> WebApp's bundle loader (*clsToProxy.getClassLoader()*).
>> *- cl* is an UrlClassLoader which is internally created by OpenEjb for its
>> own purposes and contains as resources the WebApp's WEB-INF/classes.
>>
>> What happens here is that the first time this proxy is created OpenEjb
>> actually defines it with the WebApp's bundle loader - *
>> defineClass.invoke(..,clsToProxy.getClassLoader(),...)*. Later when this
>> bean is injected again we end up in the same place to create a proxy,
>> expecting to load it with OpenEjb's internal classloader - *
>> cl.loadClass(proxyName)* - and since it knows nothing about this proxy we
>> try to define it again with the WebApp's class loader which results in a
>> LinkageError.
>>
>> Do you know how is this expected to work in OSGi? And would it be better if
>> OpenEjb both tried to load and define with the same loader? I admit this
>> should work outside OSGi, but in OSGi the two loaders are
>> potentially(almost certainly) different.
>>
>> Any help is much appreciated! :-)
>>
>> Best Regards
>> Borislav
>>
>

-- 
Jean-Baptiste Onofré
jbonofre@apache.org
http://blog.nanthrax.net
Talend - http://www.talend.com

Mime
View raw message