Skip to content

Instantly share code, notes, and snippets.

@DanielThomas
Created August 20, 2024 05:24
Show Gist options
  • Save DanielThomas/83eefaad41af33a071d9a9ee17ca8fe1 to your computer and use it in GitHub Desktop.
Save DanielThomas/83eefaad41af33a071d9a9ee17ca8fe1 to your computer and use it in GitHub Desktop.
Shared class paths mismatch due to Class-Path manifest entries
#!/bin/bash -xe
dir=$(mktemp -d)
cd "$dir"
touch manifest-empty.txt
cat << EOF > manifest-guice-all.txt
Class-Path: guice-grapher-5.1.0.jar guice-assistedinject-5.1.0.jar guice-dagger-adapter-5.1.0.jar guice-jmx-5.1.0.jar guice-jndi-5.1.0.jar guice-persist-5.1.0.jar guice-struts2-5.1.0.jar guice-servlet-5.1.0.jar guice-spring-5.1.0.jar guice-throwingproviders-5.1.0.jar guice-5.1.0.jar asm-9.6.jar guava-30.1-jre.jar failureaccess-1.0.1.jar listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar
EOF
mkdir lib
jar cvfm lib/guice-all-5.1.1-jakartaee.jar manifest-guice-all.txt
jar cvfm lib/failureaccess-1.0.1.jar manifest-empty.txt
jar cvfm lib/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar manifest-empty.txt
cat << EOF > Main.java
public class Main {
public static void main(String[] args) {
}
}
EOF
javac Main.java
jar cvfm lib/main.jar manifest-empty.txt Main.class
CP="lib/guice-all-5.1.1-jakartaee.jar:lib/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar:lib/failureaccess-1.0.1.jar:lib/main.jar"
java -XX:ArchiveClassesAtExit=application.jsa -Xlog:class+path=info -cp "$CP" Main
java -XX:SharedArchiveFile=application.jsa -Xlog:class+path=info -cp "$CP" Main
@DanielThomas
Copy link
Author

Using:

openjdk version "21.0.4" 2024-07-16 LTS
OpenJDK Runtime Environment Zulu21.36+18-SA (build 21.0.4+7-LTS)
OpenJDK 64-Bit Server VM Zulu21.36+18-SA (build 21.0.4+7-LTS, mixed mode, sharing)

Results in:

++ mktemp -d
+ dir=/tmp/tmp.ICPtDSnObf
+ cd /tmp/tmp.ICPtDSnObf
+ touch manifest-empty.txt
+ cat
+ mkdir lib
+ jar cvfm lib/guice-all-5.1.1-jakartaee.jar manifest-guice-all.txt
added manifest
+ jar cvfm lib/failureaccess-1.0.1.jar manifest-empty.txt
added manifest
+ jar cvfm lib/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar manifest-empty.txt
added manifest
+ cat
+ javac Main.java
+ jar cvfm lib/main.jar manifest-empty.txt Main.class
added manifest
adding: Main.class(in = 253) (out= 189)(deflated 25%)
+ CP=lib/guice-all-5.1.1-jakartaee.jar:lib/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar:lib/failureaccess-1.0.1.jar:lib/main.jar
+ java -XX:ArchiveClassesAtExit=application.jsa -Xlog:class+path=info -cp lib/guice-all-5.1.1-jakartaee.jar:lib/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar:lib/failureaccess-1.0.1.jar:lib/main.jar Main
[0.001s][info][class,path] bootstrap loader class path=/usr/lib/jvm/zulu-21-amd64/lib/modules
[0.015s][info][class,path] Expecting BOOT path=/usr/lib/jvm/zulu-21-amd64/lib/modules
[0.015s][info][class,path] Expecting -Djava.class.path=
[0.015s][info][class,path] checking shared classpath entry: /usr/lib/jvm/zulu-21-amd64/lib/modules
[0.015s][info][class,path] ok
[0.015s][info][class,path] app loader class path=lib/guice-all-5.1.1-jakartaee.jar:lib/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar:lib/failureaccess-1.0.1.jar:lib/main.jar
[0.015s][info][class,path] opened: lib/guice-all-5.1.1-jakartaee.jar
[0.015s][info][class,path] found Class-Path: guice-grapher-5.1.0.jar guice-assistedinject-5.1.0.jar guice-dagger-adapter-5.1.0.jar guice-jmx-5.1.0.jar guice-jndi-5.1.0.jar guice-persist-5.1.0.jar guice-struts2-5.1.0.jar guice-servlet-5.1.0.jar guice-spring-5.1.0.jar guice-throwingproviders-5.1.0.jar guice-5.1.0.jar asm-9.6.jar guava-30.1-jre.jar failureaccess-1.0.1.jar listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar
[0.015s][info][class,path] library (non-existent) = lib/guice-grapher-5.1.0.jar
[0.015s][info][class,path] non-existent Class-Path entry lib/guice-grapher-5.1.0.jar
[0.015s][info][class,path] library (non-existent) = lib/guice-assistedinject-5.1.0.jar
[0.015s][info][class,path] non-existent Class-Path entry lib/guice-assistedinject-5.1.0.jar
[0.015s][info][class,path] library (non-existent) = lib/guice-dagger-adapter-5.1.0.jar
[0.015s][info][class,path] non-existent Class-Path entry lib/guice-dagger-adapter-5.1.0.jar
[0.015s][info][class,path] library (non-existent) = lib/guice-jmx-5.1.0.jar
[0.015s][info][class,path] non-existent Class-Path entry lib/guice-jmx-5.1.0.jar
[0.015s][info][class,path] library (non-existent) = lib/guice-jndi-5.1.0.jar
[0.015s][info][class,path] non-existent Class-Path entry lib/guice-jndi-5.1.0.jar
[0.015s][info][class,path] library (non-existent) = lib/guice-persist-5.1.0.jar
[0.015s][info][class,path] non-existent Class-Path entry lib/guice-persist-5.1.0.jar
[0.015s][info][class,path] library (non-existent) = lib/guice-struts2-5.1.0.jar
[0.015s][info][class,path] non-existent Class-Path entry lib/guice-struts2-5.1.0.jar
[0.016s][info][class,path] library (non-existent) = lib/guice-servlet-5.1.0.jar
[0.016s][info][class,path] non-existent Class-Path entry lib/guice-servlet-5.1.0.jar
[0.016s][info][class,path] library (non-existent) = lib/guice-spring-5.1.0.jar
[0.016s][info][class,path] non-existent Class-Path entry lib/guice-spring-5.1.0.jar
[0.016s][info][class,path] library (non-existent) = lib/guice-throwingproviders-5.1.0.jar
[0.016s][info][class,path] non-existent Class-Path entry lib/guice-throwingproviders-5.1.0.jar
[0.016s][info][class,path] library (non-existent) = lib/guice-5.1.0.jar
[0.016s][info][class,path] non-existent Class-Path entry lib/guice-5.1.0.jar
[0.016s][info][class,path] library (non-existent) = lib/asm-9.6.jar
[0.016s][info][class,path] non-existent Class-Path entry lib/asm-9.6.jar
[0.016s][info][class,path] library (non-existent) = lib/guava-30.1-jre.jar
[0.016s][info][class,path] non-existent Class-Path entry lib/guava-30.1-jre.jar
[0.016s][info][class,path] opened: lib/failureaccess-1.0.1.jar
[0.016s][info][class,path] library = lib/failureaccess-1.0.1.jar
[0.016s][info][class,path] opened: lib/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar
[0.016s][info][class,path] library = lib/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar
[0.016s][info][class,path] opened: lib/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar
[0.016s][info][class,path] opened: lib/failureaccess-1.0.1.jar
[0.016s][info][class,path] opened: lib/main.jar
[0.024s][info][class,path] add boot shared path (jrt) /usr/lib/jvm/zulu-21-amd64/lib/modules
[0.024s][info][class,path] add app shared path (jar) lib/guice-all-5.1.1-jakartaee.jar
[0.024s][info][class,path] add app shared path (jar) lib/failureaccess-1.0.1.jar
[0.024s][info][class,path] add app shared path (jar) lib/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar
[0.024s][info][class,path] add app shared path (jar) lib/main.jar
+ java -XX:SharedArchiveFile=application.jsa -Xlog:class+path=info -cp lib/guice-all-5.1.1-jakartaee.jar:lib/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar:lib/failureaccess-1.0.1.jar:lib/main.jar Main
[0.002s][info][class,path] bootstrap loader class path=/usr/lib/jvm/zulu-21-amd64/lib/modules
[0.015s][info][class,path] Expecting BOOT path=/usr/lib/jvm/zulu-21-amd64/lib/modules
[0.015s][info][class,path] Expecting -Djava.class.path=
[0.015s][info][class,path] checking shared classpath entry: /usr/lib/jvm/zulu-21-amd64/lib/modules
[0.015s][info][class,path] ok
[0.015s][info][class,path] Expecting BOOT path=/usr/lib/jvm/zulu-21-amd64/lib/modules
[0.015s][info][class,path] Expecting -Djava.class.path=lib/guice-all-5.1.1-jakartaee.jar:lib/failureaccess-1.0.1.jar:lib/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar:lib/main.jar
[0.015s][info][class,path] checking shared classpath entry: /usr/lib/jvm/zulu-21-amd64/lib/modules
[0.015s][info][class,path] ok
[0.015s][info][class,path] checking shared classpath entry: lib/guice-all-5.1.1-jakartaee.jar
[0.015s][info][class,path] ok
[0.015s][info][class,path] checking shared classpath entry: lib/failureaccess-1.0.1.jar
[0.015s][info][class,path] ok
[0.015s][info][class,path] checking shared classpath entry: lib/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar
[0.015s][info][class,path] ok
[0.015s][info][class,path] checking shared classpath entry: lib/main.jar
[0.015s][info][class,path] ok
[0.015s][info][class,path] LCP length for app classpath (dumptime: 4, runtime: 4)
[0.015s][info][class,path] [APP classpath mismatch, actual: -Djava.class.path=lib/guice-all-5.1.1-jakartaee.jar:lib/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar:lib/failureaccess-1.0.1.jar:lib/main.jar
[0.015s][warning][cds       ] shared class paths mismatch
[0.015s][warning][cds,dynamic] Unable to use shared archive. The top archive failed to load: application.jsa

@DanielThomas
Copy link
Author

The reason for this unusual Class-Path entry with missing libraries is the Gradle Shadow plugin:

GradleUp/shadow#324

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment