Class-Path (in jar file) semantics different between Java 11 and 13 (on Windows)?
Jaikiran Pai
jai.forums2013 at gmail.com
Mon Nov 18 15:01:39 UTC 2019
Imagine 2 jar files. One called helloworld.jar which contains just a
single org.myapp.HelloWorld class which prints to System.out from its
main method. The other jar called manifest-cp-test.jar. This
manifest-cp-test.jar contains (only a) META-INF/MANIFEST.MF with the
following content:
Manifest-Version: 1.0
Class-Path: /C:/helloworld.jar
Main-Class: org.myapp.HelloWorld
So this manifest-cp-test.jar has a Main-Class entry which points to the
HelloWorld class that belongs in the other helloworld.jar file. Both the
helloworld.jar and the manifest-cp-test.jar reside at C:\ on a Windows
system.
When run using Java 11, this runs correctly and prints the HelloWorld
message:
C:\>jdk-11.0.2\bin\java -jar manifest-cp-test.jar
Hello World
However, when run using Java 13 (and even latest upstream Java 14) on
the same Windows system, this now runs into a ClassNotFoundException:
Java 13:
C:\>jdk-13.0.1\bin\java -jar manifest-cp-test.jar
Error: Could not find or load main class org.myapp.HelloWorld
Caused by: java.lang.ClassNotFoundException: org.myapp.HelloWorld
Java 14:
C:\>jdk-14\bin\java -jar manifest-cp-test.jar
Error: Could not find or load main class org.myapp.HelloWorld
Caused by: java.lang.ClassNotFoundException: org.myapp.HelloWorld
Adding the "-Djdk.net.URLClassPath.showIgnoredClassPathEntries=true"
debug flag to the java launch command shows:
C:\>jdk-13.0.1\bin\java
-Djdk.net.URLClassPath.showIgnoredClassPathEntries=true
-jar manifest-cp-test.jar
Class-Path entry: "/C:/helloworld.jar" ignored in JAR file
file:/C:/manifest-cp-
test.jar
Error: Could not find or load main class org.myapp.HelloWorld
Caused by: java.lang.ClassNotFoundException: org.myapp.HelloWorld
So this Class-Path entry is being ignored starting Java 13.
I compared the spec for Class-Path entry for Java 11[1] and Java 13[2]
and I do changes in that section. The Java 13 version doc has those 3
rules mentioned under "A Class-Path entry is valid if the following
conditions are true:". So all 3 rules should be satisfied? I guess that
then means that this style of Class-Path entry will not satisfy the "It
can be used to create a URL, by resolving it against the context JAR's
URL"? I haven't yet had the time to look into the code or read up a bit
more on what this rule actually means. Specifically what does resolve
mean here?
[1]
https://docs.oracle.com/en/java/javase/11/docs/specs/jar/jar.html#class-path-attribute
[2]
https://docs.oracle.com/en/java/javase/13/docs/specs/jar/jar.html#class-path-attribute
P.S: This is another case of Class-Path semantics which behave not just
differently in different versions of Java but different in different
subsystems of the same Java version itself. More about this has been
discussed recently in
https://mail.openjdk.java.net/pipermail/compiler-dev/2019-October/013766.html
on compiler-dev.
-Jaikiran
More information about the core-libs-dev
mailing list