tomee-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Borislav Kapukaranov <b.kapukara...@gmail.com>
Subject injection of one EJB in another in OSGi
Date Mon, 27 Feb 2012 10:39:18 GMT
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