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?
Consider the external jar files to be on their own. How do you deploy it this way anyway? $ServerRoot/xxxdomain/applications/app.ear and $ServerRoot/xxxdomain/applications/util.jar?
whatever is under applications, be it an ear, war or an exploded app is by itself. I would think they could have different class loaders (depending on app server) since you cannot share resources between different applications.
"It is almost always answered in the API" - Murali Nanchala
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?
posted 17 years ago
One more thing... There is one other option that would work but it is not a very good solution. You could put the ejb classes that you used by the util jar on your System CLASSPATH. However, it is basically a hack and not a good long term solution since you lose the ability to do hot deployments for those ejbs. Furthermore, if more dependencies start cropping up then you will be adding more and more classes to your CLASSPATH. Yuck!
Chicken Farmer ()
posted 17 years ago
Thanks for all the info and suggestions, pretty much reinforces what I found this weekend. We're using Weblogic 7.1. Under the applications directory we have our ear file. All util classes are stuck in domain\utils. And yes, all util jars are in the classpath. Yes, it is a weird design for me, also. However, the entire application is put together rather oddly, basically a lot of people with domain knowledge, and very little good OO know-how. So when someone like myself, with little domain knowledge but some OO experience comes in, you find yourself making do. The problem is I was responsible for writing the implementation, and someone else wrote the interface. The interface they provided is passed in an object that is outside the EJBs. But for me to get all the information the implementation needs to do its thing, it needs to pass values from that object to another EJB to get the actual data it needs. <soapbox>Don't even try getting into a design discussion, if y'all could actually see some of this code, you would run screaming. They're trying to change things a bit at a time as they go, but with funding the way it is, you can only do so much. I'm just content to introduce good, modular design as I go. Luckily I've gotten to work on new code. If I had to actually support existing code, I'd start to get frustrated real quick.</soapbox> Anyway, what we're thinking about doing is just packaging this util class into jar with the EJB that uses it, since right now this is the only class that actually uses it and may very well be the only class to ever use it. They also are talking about writing a UtilBean, and packaging all util classes in there with it, but I'm hoping they're just joking.
Chicken Farmer ()
posted 17 years ago
And those articles are excellent ones, I found them after posting here and pointed my co-workers to them. I started playing with the manifest files, but since I've never had the occassion to go in there and mess with them, I wasn't able to get it to work (probably because I'm declaring it wrong).
Doody calls. I would really rather that it didn't. Comfort me wise and sterile tiny ad:
Building a Better World in your Backyard by Paul Wheaton and Shawn Klassen-Koop