tomee-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Romain Manni-Bucau <rmannibu...@gmail.com>
Subject Re: injection of one EJB in another in OSGi
Date Mon, 27 Feb 2012 12:24:04 GMT
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
>

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message