You're right. Here are some snippits from the j2ee 1.4 spec:
A JAR format file (such as a.jar file,.war file, or.rar file) can
reference a .jar file by naming the referenced.jar file in aClass-
Path header in the referencing JAR file’s Manifest file. The
referenced.jar file is named using a URL relative to the URL of the
referencing JAR file.
The deployment tool must install the.jar files in a way that
preserves the relative references between the files. Typically this
is done by installing the.jar files into a directory hierarchy that
matches the original application directory hierarchy. All
referenced .jar files must appear in the logical class path of the
referencing JAR files at runtime.
Only JAR format files containing class files or resources to be
loaded directly by a standardClassLoader should be the target of
aClass-Path reference; such files are always named with a.jar
extension. Top level JAR files that are
processed by a deployment tool should not containClass-Path entries;
such entries would, by definition, reference other files external to
the deployment unit. A deployment tool is not required to process
such external references.
Given the above text the I would categorize this bug as a blocker for
1.1.1.
-dain
On Jul 11, 2006, at 10:20 AM, Mario Ruebsam wrote:
I'm not sure but I think the Class-Path entry in war files is covered
by the spec because EAR, WAR and RAR are JAR files. J2EE 1.4
excluded EAR files from that. EAR manifest files should not contain a
Class-Path entry.
packaging description from sun:
http://java.sun.com/j2ee/verified/packaging.html
Also the class path entry is relative to the war file not the WEB-
INF/classes
or WEB-INF/lib in the war file.
Thanks,
Mario
Dain Sundstrom wrote:
On Jul 11, 2006, at 8:30 AM, David Jencks wrote:
On Jul 11, 2006, at 8:03 AM, Aaron Mulder wrote:
What if the WAR is in a subdir within the EAR like foo/bar/
some.war?
Then ".." alone won't work to resolve paths relative to the EAR.
Yes, whatever relative path we might generate certainly would
have to take account of the position of the war inside the ear.
IIRC, the manifest class path is relative to the archive itself.
In this case it is relative to the some.war, so if you want
something in the foo dir, the manifest class path entry would have
to be ../../jar.jar
Also, I think all of this is out side of the spec. IIRC the spec
only talks about manifest class path entries of jar files, and
since a war is not a jar file it isn't covered by the spec.
Regardless, I think it is a good idea to support this, but I want
to clarify that I don't believe this is a certification issue.
I would think from a WAR-in-EAR, we could identify the Module ID of
the EAR, and then use the repo to construct a path to the JAR-in-
EAR
with the EAR module ID and the JAR path. Is there a reason why
that
wouldn't work?
IIUC you are suggesting that the war configuration/module keep
track of two parts of its classpath: one inside itself, for WEB-
INF/lib and WEB-INF/classes, and one inside the enclosing ear,
for the manifest classpath. This certainly seems possible to me
but I wonder what advantage it would have over only tracking
stuff in one place.
So, now I see even more possibilities:
1. copy the manifest cp entries from the ear into the war. This
would keep the war self contained, but otherwise seems like a lot
of extra work for nothing.
2. keep track of the stuff inside the war and inside the ear
separately (your proposal IIUC)
3. keep track of the war classpath based on the war location
inside the ear, so manifest classpath entries get a ../ prepended
to them (if the war was in a subdirectory in the ear, manifest cp
entries would most likely already have one or more ../ since
entries are relative to the war location).
4. keep track of the entire war classpath based on the ear
location, so the stuff in WEB-INF/[lib,classes] would have the
war location inside the ear prepended.
I'm tempted by (4). To me it says, here's the ear with a lot
of stuff inside, and you can define classloaders that access an
arbitrary subset of the stuff inside. I think this is the most
compatible with the idea that's been floating around for a while
of keeping the configuration separate from the j2ee artifact that
is is based on: i.e. copy (possibly with unpacking) the j2ee
artifact into the repo, and not into the car file: the car file
just gets pointers into the j2ee artifact to define its classloader.
Um I didn't really understand all the options, but I would like to
suggest that the class path contain patterns (the code is already
in place for this) and we resolve these patterns against the root
dir of the war. For manifest class path entries, we would just
need to prepend each entry with ../ to get outside the war dir
and prepend them to the class path with the manifest entries. For
example, the example aaron used above would result in the following:
War base dir: foo/bar/web.war/
War class path: ../../../jar.jar lib/classes lib/*.jar lib/*.zip
Final class path: foo/jar.jar
foo/bar/web.war/lib/classes
foo/bar/web.war/lib/lib.jar
foo/bar/web.war/lib/lib.zip
-dain