Originally posted by jason adam:
Not sure if this a really newbie question... or proof that the deployment we have is bass-ackwards, but here goes.
We have an ear file with all our EJB jars and our web app war. All fine and dandy. There is also a group of jar files that are grouped into a directory separate from the ear. One the util classes in one of these separate jar files happens to want to try and access a bean.
Problem is, when we try to get the home out of the context, I get a "ClassDefNotFoundError". Not good.
I've played around with manifest files, but can't get the EJB home to be found by the loader that my util class is using.
Is there a nice way of doing this, or should we really look at re-evaluating our deployment plan?
First off, it would be helpful to know which Application Server you are using since they each handle classloading slightly differently. Onto your problem...
Let me guess... your util jar is located on the System classpath, right? This means that they are going to be loaded by the System classloader, whereas the ejbs will be loaded by a separate classloader that is most likely a child of the System classloader. Therefore, the util classes will not be able to access the ejb classes however the ejb classes can access the util classes, but we already knew that didn't we...
This is similar to another common J2EE classloading problem where you have objects that are passed between the EJB Layer and the Web Layer. The class definitions for these objects must be in a place that is accessible to both the EJB CL and the Web CL.
The classes can't go in the web app since the EJB CL can't see them. In this case you are left with basically three options:
1) Put all shared classes on the System CLASSPATH.
2) Put all shared classes in each ejb-jar.
3) Put all shared classes in a jar in the ear and place a manifest dependency between each ejb-jar and the shared jar.
Option 1 is probably the simplest and it is probably want you are currently doing, however it prevents dynamic reloading of the shared classes. Furthermore, it will not work in your case (as you can see) since the util classes need access to the ejbs. BTW, from a design perspective that dependency seems a bit odd for me...
Option 2 is fairly easy, however it requires all ejbs to be redeployed if a single shared class changes and offers room for error if all ejb-jars are not updated. A good automated build process is definitely necessary here (
Ant)...
Option 3 is the solution that I recommend and is required behavior in J2EE 1.3. However, not all tools support the manifest entry so it may be a pain to configure builds. As with option 2, I highly recommend an automated build using Ant.
For more information I suggest you take a look at these two articles by Tyler Jewel:
EJB 2.0 and J2EE Packaging EJB 2.0 and J2EE Packaging, Part II Did I ever mention how much of a pain J2EE deployments can be sometimes?