Browse Source

Don't close nested jars or wrapper when parent is closed

Update `JarFile` so that the `close()` method no longer closes nested
jars or the wrapper. Prior to this commit it was possible for a parent
jar file to be garbage collected and closed even though references still
existed to the nested jars. When this happened the nested jars would get
closed and any access to entries would result in `JarFile.ensureOpen()`
throwing an `IllegalStateException`. The user would often not see this
exception directly, but rather find `ClassNotFoundException` being
thrown.

Fixes gh-31853
pull/32501/head
Phillip Webb 3 years ago
parent
commit
360eb027be
  1. 15
      spring-boot-project/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/jar/JarFile.java

15
spring-boot-project/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/jar/JarFile.java

@ -26,11 +26,8 @@ import java.net.URL; @@ -26,11 +26,8 @@ import java.net.URL;
import java.net.URLStreamHandler;
import java.net.URLStreamHandlerFactory;
import java.security.Permission;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.function.Supplier;
@ -96,8 +93,6 @@ public class JarFile extends AbstractJarFile implements Iterable<java.util.jar.J @@ -96,8 +93,6 @@ public class JarFile extends AbstractJarFile implements Iterable<java.util.jar.J
private volatile JarFileWrapper wrapper;
private final List<JarFile> nestedJars = Collections.synchronizedList(new ArrayList<>());
/**
* Create a new {@link JarFile} backed by the specified file.
* @param file the root jar file
@ -340,10 +335,8 @@ public class JarFile extends AbstractJarFile implements Iterable<java.util.jar.J @@ -340,10 +335,8 @@ public class JarFile extends AbstractJarFile implements Iterable<java.util.jar.J
+ "mechanism used to create your executable jar file");
}
RandomAccessData entryData = this.entries.getEntryData(entry.getName());
JarFile nestedJar = new JarFile(this.rootFile, this.pathFromRoot + "!/" + entry.getName(), entryData,
return new JarFile(this.rootFile, this.pathFromRoot + "!/" + entry.getName(), entryData,
JarFileType.NESTED_JAR);
this.nestedJars.add(nestedJar);
return nestedJar;
}
@Override
@ -368,12 +361,6 @@ public class JarFile extends AbstractJarFile implements Iterable<java.util.jar.J @@ -368,12 +361,6 @@ public class JarFile extends AbstractJarFile implements Iterable<java.util.jar.J
if (this.type == JarFileType.DIRECT) {
this.rootFile.close();
}
if (this.wrapper != null) {
this.wrapper.close();
}
for (JarFile nestedJar : this.nestedJars) {
nestedJar.close();
}
this.closed = true;
}
}

Loading…
Cancel
Save