Ensure that StaticResourceJars does not close cached jars
Update `StaticResourceJars` so that jars obtained via a `JarURLConnection` are only closed when caches are not being used. Fixes gh-38766
This commit is contained in:
parent
82bc9a6280
commit
da31137596
|
|
@ -115,7 +115,7 @@ class StaticResourceJars {
|
||||||
|
|
||||||
private boolean isResourcesJar(JarURLConnection connection) {
|
private boolean isResourcesJar(JarURLConnection connection) {
|
||||||
try {
|
try {
|
||||||
return isResourcesJar(connection.getJarFile());
|
return isResourcesJar(connection.getJarFile(), !connection.getUseCaches());
|
||||||
}
|
}
|
||||||
catch (IOException ex) {
|
catch (IOException ex) {
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -124,16 +124,21 @@ class StaticResourceJars {
|
||||||
|
|
||||||
private boolean isResourcesJar(File file) {
|
private boolean isResourcesJar(File file) {
|
||||||
try {
|
try {
|
||||||
return isResourcesJar(new JarFile(file));
|
return isResourcesJar(new JarFile(file), true);
|
||||||
}
|
}
|
||||||
catch (IOException | InvalidPathException ex) {
|
catch (IOException | InvalidPathException ex) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isResourcesJar(JarFile jar) throws IOException {
|
private boolean isResourcesJar(JarFile jarFile, boolean closeJarFile) throws IOException {
|
||||||
try (jar) {
|
try {
|
||||||
return jar.getName().endsWith(".jar") && (jar.getJarEntry("META-INF/resources") != null);
|
return jarFile.getName().endsWith(".jar") && (jarFile.getJarEntry("META-INF/resources") != null);
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
if (closeJarFile) {
|
||||||
|
jarFile.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,10 @@ package org.springframework.boot.web.servlet.server;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.net.JarURLConnection;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.net.URLConnection;
|
||||||
|
import java.net.URLStreamHandler;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.jar.JarEntry;
|
import java.util.jar.JarEntry;
|
||||||
|
|
@ -29,6 +32,8 @@ import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.io.TempDir;
|
import org.junit.jupiter.api.io.TempDir;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThatNoException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for {@link StaticResourceJars}.
|
* Tests for {@link StaticResourceJars}.
|
||||||
|
|
@ -86,6 +91,27 @@ class StaticResourceJarsTests {
|
||||||
assertThat(staticResourceJarUrls).isEmpty();
|
assertThat(staticResourceJarUrls).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void doesNotCloseJarFromCachedConnection() throws Exception {
|
||||||
|
File jarFile = createResourcesJar("test-resources.jar");
|
||||||
|
TrackedURLStreamHandler handler = new TrackedURLStreamHandler(true);
|
||||||
|
URL url = new URL("jar", null, 0, jarFile.toURI().toURL().toString() + "!/", handler);
|
||||||
|
new StaticResourceJars().getUrlsFrom(url);
|
||||||
|
assertThatNoException()
|
||||||
|
.isThrownBy(() -> ((JarURLConnection) handler.getConnection()).getJarFile().getComment());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void closesJarFromNonCachedConnection() throws Exception {
|
||||||
|
File jarFile = createResourcesJar("test-resources.jar");
|
||||||
|
TrackedURLStreamHandler handler = new TrackedURLStreamHandler(false);
|
||||||
|
URL url = new URL("jar", null, 0, jarFile.toURI().toURL().toString() + "!/", handler);
|
||||||
|
new StaticResourceJars().getUrlsFrom(url);
|
||||||
|
assertThatIllegalStateException()
|
||||||
|
.isThrownBy(() -> ((JarURLConnection) handler.getConnection()).getJarFile().getComment())
|
||||||
|
.withMessageContaining("closed");
|
||||||
|
}
|
||||||
|
|
||||||
private File createResourcesJar(String name) throws IOException {
|
private File createResourcesJar(String name) throws IOException {
|
||||||
return createJar(name, (output) -> {
|
return createJar(name, (output) -> {
|
||||||
JarEntry jarEntry = new JarEntry("META-INF/resources");
|
JarEntry jarEntry = new JarEntry("META-INF/resources");
|
||||||
|
|
@ -113,4 +139,27 @@ class StaticResourceJarsTests {
|
||||||
return jarFile;
|
return jarFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class TrackedURLStreamHandler extends URLStreamHandler {
|
||||||
|
|
||||||
|
private final boolean useCaches;
|
||||||
|
|
||||||
|
private URLConnection connection;
|
||||||
|
|
||||||
|
TrackedURLStreamHandler(boolean useCaches) {
|
||||||
|
this.useCaches = useCaches;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected URLConnection openConnection(URL u) throws IOException {
|
||||||
|
this.connection = new URL(u.toExternalForm()).openConnection();
|
||||||
|
this.connection.setUseCaches(this.useCaches);
|
||||||
|
return this.connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
URLConnection getConnection() {
|
||||||
|
return this.connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue