EJB programming & troubleshooting: Calling EJB Modules from several webapps
- Posted by: Eneko Gonzalez
- Posted on: January 29 2004 12:05 EST
I have 3 webapps that use the same EJBs and I want to call the EJBs from that webapps, without copying the EJBs in every webapp classes folder, so i have that EJBs in another folder (and deployed in my server, of course)
But when I try to call an EJB from one of the webapps, i've a ClassNotFoundException, 'cause mi server (Weblogic 8) is not able to find my EJB...
I've heard that the problem is that WL uses a different JVM for each app, so none of my webapps can access any EJB...
Can anyone help me to solve this? Thanks in advance :-)
- Calling EJB Modules from several webapps by Andre Fernandes on January 29 2004 12:55 EST
WebLogic uses a different CLASSLOADER, not JVM, for each application. This is the standard behaviour for any J2EE server, for it provides the desired isolation between applications (and makes their [re]deployment possible).
So a WAR in the same EAR of an EJB-jar can see automatically the EJB-jar classes/interfaces (this is also common behaviour since EJB 2.0). WARs in different EARs can't.
There are several workarounds. But first of all, you need to package the EJB "client" classes (interfaces, VOs etc.) into a separate JAR (let's call it "ejb-client.jar"). The possibilities are:
1. (I dislike this) You can put this ejb-client.jar in the server classpath, by editing the "startWebLogic.bat" file (curiously, there is no "lib/ext" folder in WLS8);
2. You can copy this ejb-client.jar into the WEB-INF/lib folder of each web application (I think BEA recommends this procedure);
3. You can try to fiddle with the application manifest file Class-Path entry, inserting a path like "../EJBEAR.ear/ejb-jar.jar"), therefore putting the EJBs original JAR in the client application classloader (there is no need of an ejb-client.jar then). This is a bit too low level, and it is hard to figure out the correct Class-Path entry;
Finally, you will only be able to use the remote interfaces when the WAR resides in a different EAR (except if you use the "1"st solution). Trying to use local interfaces will result in ClassCastExceptions. This is because when a class is loaded by two different classloaders these are considered different classes, and typecasting the JNDI lookup result will raise an exception (the solution "1" guarantees that the ejb-client.jar classes are loaded by a single higher classloader - you get no ClassCastExceptions, but changes in the interfaces will require a server restart).
These limitation are derived from the expected behaviour of a J2EE server classloader hierarchy, and you will face the same problems with WebSphere.
Hope it helps.
WebLogic uses a different CLASSLOADER, not JVM, for each application.
Oh, yes, it's true ... sorry :)
> 1. (I dislike this) You can put this ejb-client.jar in the server classpath,
I can't use it because i don't want to stop the server whenever i change an ejb.
> 2. You can copy this ejb-client.jar into the WEB-INF/lib folder of each web
> application (I think BEA recommends this procedure);
I've tried this, but i can't make it work. I've tried copying the interfaces .class files in the WEB-INF/classes too, but it doen't work either ... i just get another NoClassDefFoundError :(
Now it works ... i have copied the interfaces .class files in every WEB-INF/classes (i'll make a jar later), and the EJB modules are out of the app.
The problem was that i've got a class that calls the EJBs using JNDI, and it was in the classpath, so it couldn't access the interfaces. No, i've copied it to every WEB-INF/classes too, and it seems to work ok.
Thanks a lot :D
That makes sense: the classloader behaviour looks for classes upwards in the classloader hierarchy. If this service locator of yours was in a higher classloader it would never be able to find classes in WEB-INF/lib or WEB-INF/classes.
What you appear to be outlining is the use of a stub file created from the ejb.
What I have interpretted from your posts is:
1) create a jar file that has the interface class files
from the ejb.
2) put this jar file into the WEB-INF/lib directory of
the war file.
Is this what you are saying? The use of the term EJB "client" was confusing.
If it is then why are there procedures inplace to take the classes created from the compile of an EJB and run it through the rmic compiler to create the stub file for client use.