-
1. Another Classloader manifest problem
dokomesiter Mar 7, 2003 10:44 PM (in response to jamoville)Simpler version of the same thing, and it looks like a classloader bug (at least as of 3.0.5)???: EJB Jars must contain the utility jars they reference because they will not find them inside the EAR file (regardless of jar manifest class-path).
ie, jars must contain other jars instead of having the ear contain all the jars. (yuck)
Example:
if class A instantiates
class B which instantiates
class C
and each is in their own jar with Class-Path references
A.JAR
META-INF/MANIFEST.MF
Class-Path: B.JAR
B.JAR
META-INF/MANIFEST.MF
Class-Path: C.JAR
C.JAR
Then everything is done correctly according to the J2EE spec.
What should work:
COMBINE.EAR=(A.JAR, B.JAR, C.JAR)
ie
jar a.jar a.class ...
jar b.jar b.class ...
jar c.jar c.class ...
jar combine.ear a.jar b.jar c.jar ...
What does work:
COMBINE.EAR=(A.JAR=(B.JAR, C.JAR))
ie
jar c.jar c.class ...
jar b.jar b.class ...
jar a.jar a.class b.jar c.jar ... // bug workaround
jar combine.ear a.jar ...
In other words, the other jars have to be embedded within the first jar rather than simply packaged with the ear (look at petstore.ear's tracer.jar as an example)
Class A is an EJB
Classes B and C are utility POJOs
This ClassLoader ClassNotFound problem is easily reproducible in 10 or so lines of code, both in Servlet and RichClient applications.
What also works, and is also not very pretty, is to not use EARs at all, but dump all the jars in /deploy.
Since we have hundreds of utility jars that's gunna be ugly, and it kills "hot-deploy".
Any ideas or words of wisdom?
Thanks
Chris -
2. Re: Classloader problem with cascaded manifest
yurim Mar 9, 2003 5:50 PM (in response to jamoville)As far as I understand from:
http://www.onjava.com/lpt/a/961
referring to other libraries by specification is available only from .jar files and not from .ear files. Probably it is not a bug. -
3. Re: Classloader problem with cascaded manifest
dokomesiter Mar 10, 2003 7:57 AM (in response to jamoville)To quote a colleague of mine:
"Sorry, but that article is almost 2 years old and refers to 1.3. Out of date at best; I'm sure things have changed in 1.4 and containers have improved dramatically during that time."
And would it not be be a little silly to have utility.jar embedded inside every other jar rather than just have a single version inside the ear.
jboss way (seem very wrong)
jar a.jar a.class util1.jar util2.jar
jar b.jar b.class util1.jar util2.jar
jar c.jar c.class util1.jar util2.jar
jar combo.ear a.jar b.jar c.jar
correct way:
jar a.jar a.class
jar b.jar b.class
jar c.jar c.class
jar combo.ear a.jar b.jar c.jar util1.jar util2.jar
in either clase, the manifests of a, b, and c point to
util1.jar, util2.jar, as it
a.jar, manifest.mf
Class-Path: util1.jar util2.jar
so the only question is whether or not one needs multiple copies of the same jar file inside the container (and for us, that might be hundreds of copies of the same jar file, that seems wrong) -
4. JBoss Classloader Bug
dokomesiter Mar 10, 2003 11:32 AM (in response to jamoville)Here is an tiny standalone example showing the JBoss Classloader problem: utility jars have to be inside other jars and in web-inf/lib instead of in the EAR, even when referenced by Class-Path in manifest.
Attachment: loadbug.zip
Usage:
1. unzip
2. ant deploy
3. ant test.richclient
This is *not* how J2EE Reference Implementation (j2ee-ri) does it; instead of putting utility JARS inside ejb JARS, it puts the utility JARS in the EAR (in a /library directory relative to the ear) where all other jars inside the ear that have class-path cna laod those classes.
In JBoss it yields NoClassDefFoundError.
It looks like RI does it the right way, and JBoss does not.
Cheers,
Chris -
5. Re: Classloader problem with cascaded manifest
fred Mar 17, 2003 8:09 PM (in response to jamoville)The A_Bean.jar manifest classpath declaration is incorrect. It should read:
Class-Path: B_Util.jar A_Interface.jar
instead of:
Class-Path: B_Util.jar
Class-Path: A_Interface.jar
With that change, the test works. -
6. Re: Classloader problem with cascaded manifest
dokomesiter Mar 18, 2003 5:59 AM (in response to jamoville)You are absolutely correct, I am wrong.
In my comparison with JBoss I used the "clean" build.xml
<jar ..
with JBoss, and with RI I used the deploytool which lists each of the referenced JARs on a separate line but concatenates them in the deployment descriptor.
Sorry about the fuss, though I had done due diligence, but was very mistaken
Great catch, thanks... -
7. Re: Classloader problem with cascaded manifest
dokomesiter Mar 18, 2003 7:22 AM (in response to jamoville)Maybe JBoss isn't as egregiously wrong as thought, but on closer look at the doc it still apears to be a bug.
From Sun's online J2EE 1.3 documentation
http://java.sun.com/docs/books/tutorial/ext/basics/download.html
<near the bottom of the page>
"You can also specify multiple extension URLs by using more than one Class-Path header in the manifest. For example:
Class-Path: area.jar
Class-Path: servlet.jar
Download extensions can be "daisy chained", meaning that the manifest of one download extension can have a Class-Path header that refers to a second extension, which can refer to a third extension, and so on. "