You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by Aaron Mulder <am...@alumni.princeton.edu> on 2000/09/01 21:49:55 UTC

Tomcat + jBoss: ClassLoader Woes

	Sorry for the cross-post, but I'm looking for ideas wherever I can
find them.  I'm trying to hook up Tomcat and jBoss so I can call EJBs from
JSPs.  I believe the problems I'm having are caused by the proliferation
of ClassLoaders.
	Initially, I ran both Tomcat and jBoss in one VM, but I ran into
ClassCastExceptions when I look up EJB objects in JNDI.  That is, the
code:
	Context ctx = new InitialContext();
	UserHome home = (UserHome)ctx.lookup("User");

resulted in a ClassCastException on the returned object (whose class is
$Proxy1 in the output below).  Examinging the Proxy reveals that it does
indeed implement the interface, but the interface class was loaded in the
wrong ClassLoader:

[Default] UserHelper ClassLoader is 'AdaptiveClassLoader(  )'
[Default] UserHome ClassLoader is 'AdaptiveClassLoader(  )'
[Default] $Proxy1 ClassLoader is 'sun.rmi.server.LoaderHandler$Loader@5a18ac'
[Default]   $Proxy1 implements 'com.coretech.user.UserHome' from
ClassLoader 'sun.rmi.server.LoaderHandler$Loader@5a18ac'
[Default]   $Proxy1 implements 'javax.ejb.Handle' from ClassLoader
'sun.misc.Launcher$AppClassLoader@404536'

	So the interface is loaded by Tomcat's "AdaptiveClassLoader" but
the Proxy coming out of JNDI is loaded by an RMI ClassLoader, which I
assume is not aware of the AdaptiveClassLoader - despite the fact that it
is the current ClassLoader for "UserHelper", the class executing this
code.

	After this, I ran jBoss and Tomcat separately, and I haven't been
able to get that to work either.  If I load the jBoss JNDI classes in
tomcat/lib, then I get a ClassNotFoundException on "UserHome" when I use
the code above.  This kind of makes sense, since the UserHome class is in
the context/WEB-INF/classes directory, so you wouldn't necessarily expect
the classes on the system classpath to be aware of it.
	If I instead put the jBoss JNDI classes in context/WEB-INF/lib,
then I get a ClassNotFoundException on them when I try to create the JNDI
InitialContext.  Here's a partial trace:

javax.naming.NoInitialContextException: Cannot instantiate class:
org.jnp.interfaces.NamingContextFactory.  Root exception is
java.lang.ClassNotFoundException: org.jnp.interfaces.NamingContextFactory
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClassInternal(Unknown Source)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Unknown Source)
        at com.sun.naming.internal.VersionHelper12.loadClass(Unknown Source)
        at javax.naming.spi.NamingManager.getInitialContext(Unknown Source)
        at javax.naming.InitialContext.getDefaultInitCtx(Unknown Source)
        at javax.naming.InitialContext.init(Unknown Source)
        at javax.naming.InitialContext.<init>(Unknown Source)

	So again, it looks like the classes in context/WEB-INF/lib are
loaded by the AdaptiveClassLoader, and here the JNDI implementation is not
aware of AdaptiveClassLoader, despite the fact that it is the current
ClassLoader for the code executing the call.

	Finally, if I put all my classes (User, UserHome, UserHelper,
jBoss JNDI, etc.) in tomcat/classes and tomcat/lib, then everything
works.  But this is pretty far from ideal - now this one app has taken
over Tomcat instead of having the nice web app separation.
	So I suspect I can skin this cat in several ways, and I'm looking
for any suggestions:

 - How can I get Sun's JNDI implementation to recognize
AdaptiveClassLoader as the current/parent ClassLoader?

 - How can I get Sun's RMI implementation to recognize Adaptive
ClassLoader as the current/parent ClassLoader?

 - Are there any other ways to get this to work other than putting all the
app classes on the Tomcat ClassPath?

Thanks,
	Aaron


Re: Tomcat + jBoss: ClassLoader Woes

Posted by Paul Speed <ps...@progeeks.com>.
Hello,

	Welcome to the wonderful world of EJB. :)

	We experience the same problems with Weblogic.  Unfortunately,
it seems like the classloaders that are used by JNDI/RMI in our 
specific cases are not respecting the current classloader as a parent.

	Since it's a problem with those specific classloaders using
the system classloader instead of the current classloader, I'm not
sure there is any way around it.

	Hopefully I will be proven wrong.
	-Paul

Aaron Mulder wrote:
> 
>         Sorry for the cross-post, but I'm looking for ideas wherever I can
> find them.  I'm trying to hook up Tomcat and jBoss so I can call EJBs from
> JSPs.  I believe the problems I'm having are caused by the proliferation
> of ClassLoaders.
>         Initially, I ran both Tomcat and jBoss in one VM, but I ran into
> ClassCastExceptions when I look up EJB objects in JNDI.  That is, the
> code:
>         Context ctx = new InitialContext();
>         UserHome home = (UserHome)ctx.lookup("User");
> 
> resulted in a ClassCastException on the returned object (whose class is
> $Proxy1 in the output below).  Examinging the Proxy reveals that it does
> indeed implement the interface, but the interface class was loaded in the
> wrong ClassLoader:
> 
> [Default] UserHelper ClassLoader is 'AdaptiveClassLoader(  )'
> [Default] UserHome ClassLoader is 'AdaptiveClassLoader(  )'
> [Default] $Proxy1 ClassLoader is 'sun.rmi.server.LoaderHandler$Loader@5a18ac'
> [Default]   $Proxy1 implements 'com.coretech.user.UserHome' from
> ClassLoader 'sun.rmi.server.LoaderHandler$Loader@5a18ac'
> [Default]   $Proxy1 implements 'javax.ejb.Handle' from ClassLoader
> 'sun.misc.Launcher$AppClassLoader@404536'
> 
>         So the interface is loaded by Tomcat's "AdaptiveClassLoader" but
> the Proxy coming out of JNDI is loaded by an RMI ClassLoader, which I
> assume is not aware of the AdaptiveClassLoader - despite the fact that it
> is the current ClassLoader for "UserHelper", the class executing this
> code.
> 
>         After this, I ran jBoss and Tomcat separately, and I haven't been
> able to get that to work either.  If I load the jBoss JNDI classes in
> tomcat/lib, then I get a ClassNotFoundException on "UserHome" when I use
> the code above.  This kind of makes sense, since the UserHome class is in
> the context/WEB-INF/classes directory, so you wouldn't necessarily expect
> the classes on the system classpath to be aware of it.
>         If I instead put the jBoss JNDI classes in context/WEB-INF/lib,
> then I get a ClassNotFoundException on them when I try to create the JNDI
> InitialContext.  Here's a partial trace:
> 
> javax.naming.NoInitialContextException: Cannot instantiate class:
> org.jnp.interfaces.NamingContextFactory.  Root exception is
> java.lang.ClassNotFoundException: org.jnp.interfaces.NamingContextFactory
>         at java.net.URLClassLoader$1.run(Unknown Source)
>         at java.security.AccessController.doPrivileged(Native Method)
>         at java.net.URLClassLoader.findClass(Unknown Source)
>         at java.lang.ClassLoader.loadClass(Unknown Source)
>         at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
>         at java.lang.ClassLoader.loadClass(Unknown Source)
>         at java.lang.ClassLoader.loadClassInternal(Unknown Source)
>         at java.lang.Class.forName0(Native Method)
>         at java.lang.Class.forName(Unknown Source)
>         at com.sun.naming.internal.VersionHelper12.loadClass(Unknown Source)
>         at javax.naming.spi.NamingManager.getInitialContext(Unknown Source)
>         at javax.naming.InitialContext.getDefaultInitCtx(Unknown Source)
>         at javax.naming.InitialContext.init(Unknown Source)
>         at javax.naming.InitialContext.<init>(Unknown Source)
> 
>         So again, it looks like the classes in context/WEB-INF/lib are
> loaded by the AdaptiveClassLoader, and here the JNDI implementation is not
> aware of AdaptiveClassLoader, despite the fact that it is the current
> ClassLoader for the code executing the call.
> 
>         Finally, if I put all my classes (User, UserHome, UserHelper,
> jBoss JNDI, etc.) in tomcat/classes and tomcat/lib, then everything
> works.  But this is pretty far from ideal - now this one app has taken
> over Tomcat instead of having the nice web app separation.
>         So I suspect I can skin this cat in several ways, and I'm looking
> for any suggestions:
> 
>  - How can I get Sun's JNDI implementation to recognize
> AdaptiveClassLoader as the current/parent ClassLoader?
> 
>  - How can I get Sun's RMI implementation to recognize Adaptive
> ClassLoader as the current/parent ClassLoader?
> 
>  - Are there any other ways to get this to work other than putting all the
> app classes on the Tomcat ClassPath?
> 
> Thanks,
>         Aaron
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tomcat-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: tomcat-dev-help@jakarta.apache.org

RE: [jBoss-Dev] Tomcat + jBoss: ClassLoader Woes

Posted by marc fleury <ma...@telkel.com>.
>	So I suspect I can skin this cat in several ways, and I'm looking
> for any suggestions:
>
>  - How can I get Sun's JNDI implementation to recognize
> AdaptiveClassLoader as the current/parent ClassLoader?
>
>  - How can I get Sun's RMI implementation to recognize Adaptive
> ClassLoader as the current/parent ClassLoader?
>
>  - Are there any other ways to get this to work other than putting all the
> app classes on the Tomcat ClassPath?

Ok sebastien has got a working version of Tomcat and jboss2 right here at
Telkel.  It seems this needs serious packaging and documentation.  As we
pointed out there are also classloader issues with inVM invocations, but the
problems you describe (non InVM) we don't see.

Either way, if *you* Aaron of all people can't get it to work easily it
means we have a problem in usability and installation.  (oh wait I just see
you are crossposting, I wasn't paying attention).

Ok, there might be other ways to do this right.  When Catalina comes with
interceptor we will need the "contextClassLoader" to be set with the right
CL attached to an application (as opposed to a container, or stack of
interceptors as it is right now).

I am assigning Sebastien full time to get a product out, something
integrated.  As I mentioned we already have the "serialized" version working
(i.e. no optimization inVM == slow) but that works and putting it out is
just packaging.  The CL visibility is a bit more complex and I believe
should rely on the managing infrastructure, which for us is JMX and for the
tomcat crew is avalon (?).  I believe  that the dynamic adding and removing
of apps is a biggy too, it is working great in jboss but I have no real
insights in how this is done in Tomcat.  EAR management is going to be the
key to it all.

In any case we will report the findings and modifications to these lists.

I don't know about you guys (tomcat) but we are seeing *tremendous* demand
for this integrated stack of J2EE products, and as we said before are really
looking forward to Catalina.  However in the mean time we will try to get
the stuff with Tomcat inVM working... keep an open mind.

PLgC,

marc