When using the Spring 5.1.7 application with enabled Java SecurityManager on Java 11, the application wont start - on Java 8 everything works.
The problem is how class ZipFile changed from 8 to 11. When loading class resource from jar file and using security manager, JDK checks the jar LOC header.
static JarFile checkJar(JarFile jar) throws IOException {
if (System.getSecurityManager() != null &&
!DISABLE_JAR_CHECKING &&
!zipAccess.startsWithLocHeader(jar) <------
) {
IOException x = new IOException("Invalid Jar file");
try {
jar.close();
....
On Java 8 this information is stored as boolean field directly on ZipFile class, but on 11 this field has moved to the inner static class Source
of another inner static class CleanableResource
.
// Java 8
// https://github.com/bpupadhyaya/openjdk-8/blob/master/jdk/src/share/classes/java/util/zip/ZipFile.java
public
class ZipFile implements ZipConstants, Closeable {
...
private final boolean locsig; <--------
...
}
// Java 11
// https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/java/util/zip/ZipFile.java
public class ZipFile implements ZipConstants, Closeable {
private final String name; // zip file name
...
private final @Stable CleanableResource res; <--------
...
private static class CleanableResource implements Runnable {
final Set<InputStream> istreams;
...
Source zsrc; <-------
...
private static class Source {
private final Key key; // the key in files
...
private final boolean startsWithLoc; <--------
...
}
}
}
Now for some reason, when Spring looks for a jar resource via class PathMatchingResourcePatternResolver
and method doFindPathMatchingJarResources
it closes that jar in finally block, which dereferences the zsrc (Source
) field on CleanableResource - https://github.com/openjdk/jdk/blob/3c214ff134e5b8b922eaf695a2a113c829ef74a1/src/java.base/share/classes/java/util/zip/ZipFile.java#L800
Afterwards, when JDK is checking for LOC header during class resource loading, the NPE is thrown, class is not loaded and the whole application crashes.
Im not really sure if this is even Spring bug, but would like to hear an opinion of a Spring developer.
Comment From: bclozel
Sorry it took us so long to respond.
In the meantime, Spring Framework 6.x requires Java 17 and we've deprecated our support for the Java SecurityManager in #26901, following the lead of the JDK itself. I don't think investigating this issue further would be a good investment of the team's time, so I'm closing this issue as a result.