[jboss-dev-forums] [Design of EJB 3.0] - Re: EJB3 Classloader Leak (EJBTHREE-1442)
ALRubinger
do-not-reply at jboss.com
Thu Sep 11 16:00:53 EDT 2008
I've got a patch that fixes the test in Sun JDK6, and JDK5 i386. Still continues to fail, however, in JDK x86_64.
This solution will also address the web injection issue, but redefining the Proxy in the caller's CL if necessary.
S,
ALR
Index: src/main/java/org/jboss/ejb3/proxy/factory/session/SessionProxyFactoryBase.java
| ===================================================================
| --- src/main/java/org/jboss/ejb3/proxy/factory/session/SessionProxyFactoryBase.java (revision 78381)
| +++ src/main/java/org/jboss/ejb3/proxy/factory/session/SessionProxyFactoryBase.java (working copy)
| @@ -197,30 +197,6 @@
| Constructor<?> constructor = this.getConstructorsProxySpecificBusinessInterface().get(
| businessInterfaceName.trim());
|
| - /*
| - * In place for web injection (isolated CL)
| - */
| - ClassLoader tcl = Thread.currentThread().getContextClassLoader();
| - try
| - {
| - // See if we can get at the bean class from the TCL
| - Class<?> businessInterfaceClass = Class.forName(businessInterfaceName, false, tcl);
| -
| - // If so, use the TCL to generate the Proxy class, not the Container CL
| - Set<Class<?>> businessInterfaces = new HashSet<Class<?>>();
| - businessInterfaces.add(businessInterfaceClass);
| - constructor = this.createProxyConstructor(businessInterfaces, tcl);
| -
| - }
| - catch (LinkageError le)
| - {
| - // Ignore
| - }
| - catch (ClassNotFoundException cce)
| - {
| - // Ignore
| - }
| -
| // Ensure the constructor was found
| assert constructor != null : "No business proxy constructor for \"" + businessInterfaceName
| + "\" was found; not created at start() properly? Bad value bound as RefAddr in JNDI?";
| @@ -229,8 +205,11 @@
| SessionProxyInvocationHandler handler = this
| .createBusinessInterfaceSpecificInvocationHandler(businessInterfaceName);
|
| - // Create a new Proxy instance, and return
| - return constructor.newInstance(handler);
| + // Create a new Proxy instance
| + Object proxy = constructor.newInstance(handler);
| +
| + // Return
| + return proxy;
| }
| catch (Throwable t)
| {
| Index: src/main/java/org/jboss/ejb3/proxy/objectfactory/session/SessionProxyObjectFactory.java
| ===================================================================
| --- src/main/java/org/jboss/ejb3/proxy/objectfactory/session/SessionProxyObjectFactory.java (revision 78381)
| +++ src/main/java/org/jboss/ejb3/proxy/objectfactory/session/SessionProxyObjectFactory.java (working copy)
| @@ -21,8 +21,12 @@
| */
| package org.jboss.ejb3.proxy.objectfactory.session;
|
| +import java.lang.reflect.InvocationHandler;
| +import java.lang.reflect.Proxy;
| +import java.util.HashSet;
| import java.util.List;
| import java.util.Map;
| +import java.util.Set;
|
| import javax.naming.Name;
|
| @@ -129,6 +133,65 @@
| proxy = sFactory.createProxyBusiness(businessInterface);
| log.debug("Created Proxy of type " + proxy.getClass().getSimpleName() + " for EJB3 Business Interface: "
| + businessInterface);
| +
| + /*
| + * We've got to ensure that the Proxy will be assignable to the target
| + * within this CL
| + */
| +
| + // Get the TCL
| + ClassLoader tcl = Thread.currentThread().getContextClassLoader();
| +
| + // Get the Proxy's CL
| + ClassLoader proxyCl = proxy.getClass().getClassLoader();
| +
| + // If the classloaders are not equal
| + if (tcl != proxyCl)
| + {
| + /*
| + * Reconstruct/redefine the Proxy in our CL
| + */
| +
| + // Get the Proxy Class
| + Class<?> proxyClass = proxy.getClass();
| +
| + // Ensure we've got a Proxy
| + assert Proxy.isProxyClass(proxyClass) : "Assumed Proxy is not an instance of " + Proxy.class.getName();
| +
| + // Get the InvocationHandler
| + InvocationHandler handler = Proxy.getInvocationHandler(proxy);
| +
| + // Get the Interfaces
| + Class<?>[] proxyInterfaces = proxyClass.getInterfaces();
| +
| + // Make a Set to hold the redefined classes
| + Set<Class<?>> ourClInterfaces = new HashSet<Class<?>>();
| +
| + // For each interface defined by the Proxy
| + for (Class<?> proxyInterface : proxyInterfaces)
| + {
| + // Get the FQN
| + String proxyInterfaceName = proxyInterface.getName();
| +
| + // Redefine the class in our CL
| + Class<?> ourDefinedProxyInterface = null;
| + try
| + {
| + ourDefinedProxyInterface = Class.forName(proxyInterfaceName, false, tcl);
| + }
| + catch (ClassNotFoundException e)
| + {
| + throw new RuntimeException("Can not find interface declared by Proxy in our CL + " + tcl, e);
| + }
| +
| + // Add the Class to the Set
| + ourClInterfaces.add(ourDefinedProxyInterface);
| + }
| +
| + // Redefine the Proxy in our CL
| + proxy = Proxy.newProxyInstance(tcl, ourClInterfaces.toArray(new Class<?>[]
| + {}), handler);
| + }
| }
| else
| {
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4175974#4175974
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4175974
More information about the jboss-dev-forums
mailing list