-
1. Re: J2EE classloading question (I've read the CL wiki topics
jaikiran May 4, 2006 1:52 PM (in response to ljnelson)NoClassDefFoundException, means that the classes/jars reffered by config.ConfigAnchor, through its import statements or extends clause or through some other means, is NOT present in the classpath. Make available the related classes/jars in the classpath.
Remember, ClassNotFoundException and NoClassDefFoundException are two different things. -
2. Re: J2EE classloading question (I've read the CL wiki topics
ljnelson May 4, 2006 2:14 PM (in response to ljnelson)Yes, thank you. The specific error is:
NoClassDefFoundError: No ClassLoaders found for config.ConfigAnchor
...which is a JBoss-specific error, I have to guess.
I was wrong in the sense that a Class.forName() is not happening; there is a specific reference to config.ConfigAnchor. So, as you say, config.ConfigAnchor is not showing up in the classpath, even though I have all the references (MANIFEST.MF Class-Path entries) in place properly.
Now what is weird to me is this: I understand how this error would occur if you simply look at the situation from the ear's point of view. In there, you have a framework.jar library that contains a normal static reference to config.ConfigAnchor. If the code should ever flow in that direction, you'll get a NoClassDefFoundError, because config.ConfigAnchor is not present in framework.jar. All fine and good.
But what I do NOT understand is that we're looking at this from the standpoint of the war file. That is, the call graph starts from StartupServlet.init() (loaded by the webapp loader). I would THINK that framework.jar would be added to the classpath of the webapp loader by virtue of the MANIFEST.MF entry. That would mean that the framework.jar, the StartupServlet.class and the config.ConfigAnchor.class would all be in the classpath of the webapp loader. That is not what I'm seeing.
It almost looks like JBoss is doing something weird or stupid and is adding the ear jars to the ear loader's classpath, which of course is not correct according to J2EE1.4. That is, jars in the ear are supposed to be sort of dormant or invisible until they're referenced by someone else's classpath. In this case, that means that my case should work, because framework.jar would be not-present-in-any-classpath until the webapp loader sucked it in via the war file's manifest.
Laird -
3. Re: J2EE classloading question (I've read the CL wiki topics
ljnelson May 4, 2006 2:30 PM (in response to ljnelson)Let me refine my last post. I believe it is the specification's intention that "normal" utility jars in an ear are available for inclusion in a classpath, but should not be included in that classpath by default.
So framework.jar can be roped in to someone else's classpath by way of a MANIFEST.MF Class-Path: entry, but should NOT be dumped into a classpath by default.
For that matter--and I freely admit ignorance here--why does the ear loader need a classpath inside it at all? It seems that one must be in place. -
4. Re: J2EE classloading question (I've read the CL wiki topics
ljnelson May 4, 2006 2:48 PM (in response to ljnelson)Since I'm just talking to myself here, I figure I'll do it here so others can find this in a Google search later.
To illustrate how most (every other) environments handle classloading and Manifest Class-Path entries, try this little experiment.
Create three jars, a.jar, b.jar and c.jar. Give a.jar and b.jar manifest files that reference c.jar.
Now point a URLClassLoader at a, and another one at b.jar.
Although they are, in some sense, "sharing" a single copy of c.jar, they will each get different versions of the classes contained in c.jar. That's because the Manifest Class-Path entry will effectively just-in-time expand the classpath before any loading takes place.
This is part of the jar specification.
By extension, it is also required behavior in J2EE 1.4, which requires that implementors respect the jar specification.
That means that if you have a war file with a manifest class-path entry, whatever classpath its loader has must be augmented right off the bat with whatever is in its manifest.
So if a war file loader is, in any respect, ultimately a URLClassLoader with a URL of wherever-the-war-file-is and basically nothing else, then its classpath must be immediately augmented to contain whatever the Manifest says. So the loader in this stupid example would have a class path of {wherever-the-war-file-is, some-jar-the-war-file-references-via-its-manifest, some-other-jar-similarly-referenced}. This would happen and would take place before any other class loading occurs within that war.
(Note again this is exactly what happens with URLClassLoaders right out of the box.)
This means that because webapp loaders are bound by the servlet and J2EE specifications to "look inward first", anything roped in via this manifest mechanism will have the same visibility as anything contained in WEB-INF/classes or WEB-INF/lib. That's the intention, anyway.
This does not appear to be what JBoss 4.0.3 is doing. Either the webapp manifest is ignored (this is not true; in my case I can see classes inside framework.jar), or the initiating loader of framework.jar is not correctly being set by the webapp loader to itself. What I mean by that is from the standpoint of any code inside the webapp, framework.jar in my case should appear (from a classloading perspective) as though it were dumped in WEB-INF/lib.
Since this behavior is free out of the box with URLClassLoaders, I have to assume that the Tomcat classloader that loads webapps is doing something odd, or the JBoss subclass thereof is doing something odd. -
5. Re: J2EE classloading question (I've read the CL wiki topics
ljnelson May 4, 2006 5:02 PM (in response to ljnelson)...and my .ear as built deploys just fine on Sun's reference application server, which handles manifest class-path entries properly.
OK, time to figure out how to beat JBoss with a lead pipe sufficiently hard to convince it to obey the specification.... -
6. Re: J2EE classloading question (I've read the CL wiki topics
cdreyer1 Dec 1, 2006 6:40 AM (in response to ljnelson)Did you ever find a solution to this problem?
In the wiki
http://wiki.jboss.org/wiki/Wiki.jsp?page=GetClassNotFoundExceptionOrNoClassDefFoundError
this issue is mentioned under the heading "The class is not visible from where it is being loaded".
I know it does not help much, but someone was/is aware of this.