[Design of EJB 3.0] - Re: Classloading problem in proxy factories
by bstansberry@jboss.com
"ALRubinger" wrote : To explain the reason that TCL code is in place...
|
| Without it, when performing web injection (which, by servlet spec, uses an isolated CL), we get:
|
| java.lang.IllegalArgumentException: failed to set value Proxy to jboss.j2ee:ear=tx_stateful_web.ear,jar=tx_stateful_web_ejb.jar,name=StatefulTestBean,service=EJB3 implementing [interface org.jboss.ejb3.proxy.intf.StatefulSessionProxy, interface org.jboss.ejb3.proxy.intf.SessionProxy, interface org.jboss.ejb3.proxy.intf.EjbProxy, interface somepackage.RemoteIF] on field private somepackage.RemoteIFsomepackage.TxServlet.remoteBean
|
| So even though "somepackage.RemoteIF" is implemented by the Proxy, it clashes with the destination target because the CLs are not equal.
|
Hmm, seems to me it should clash. I guess the idea is if it's a remote interface, treat the webapp as if it's a remote client? Yeah, I guess that makes sense.
"ALRubinger" wrote :
| "bstansberry" wrote : Perhaps this is a sign of a classloader leak? Proxy.getProxyClass(...) is maintaining a cache of proxy classes
|
| I'm not sure this is true, if I'm reading the source and comments from Proxy.getProxyClass correctly:
|
| /*
| | * Note that we need not worry about reaping the cache for
| | * entries with cleared weak references because if a proxy class
| | * has been garbage collected, its class loader will have been
| | * garbage collected as well, so the entire cache will be reaped
| | * from the loaderToCache map.
| | */
|
Yeah, I think I was wrong. I saw that but got tangled up in thinking about classloaders. Hmm, as I think more, I'm getting more tangled -- so, I'll continue thinking before I comment more.
anonymous wrote :
| To move forward, how about we also catch and ignore the LinkageError (to get the proxy-clustered tests passing), and I'll have to proceed with EJBTHREE-1442 to see if this is indeed the source of a CL leak.
|
I think catching the error is good. How about also trying to limit this code path? E.g. something like:
| /*
| * 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);
| Class<?> ourBusinessInterfaceClass = this.getClassLoader().loadClass(businessInterfaceName);
|
| if (!businessInterfaceClass.equals(ourBusinessInterfaceClass))
| {
| // 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 (ClassNotFoundException cce)
| {
| // Ignore
| }
| catch (LinkageError le)
| {
| // Ignore
| }
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4172829#4172829
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4172829
16 years, 5 months