From ccfc47091cec689ecc6475715854750d4a58670b Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Tue, 19 Aug 2014 13:49:55 +0100 Subject: [PATCH] Fix URL filtering when loading from a directory The ExplodedArchive would erroneously always attempt to filter its contents (and thereby shield them from a classloader that wrapped it) even if they haven't been explicitly provided. See gh-1352 --- .../boot/loader/archive/ExplodedArchive.java | 16 ++++++++------- .../loader/archive/ExplodedArchiveTests.java | 20 +++++++++++++++++++ .../boot/loader/jar/JarFileTests.java | 2 ++ 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/archive/ExplodedArchive.java b/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/archive/ExplodedArchive.java index cdfdb430a5..66b9eb9afa 100644 --- a/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/archive/ExplodedArchive.java +++ b/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/archive/ExplodedArchive.java @@ -56,7 +56,7 @@ public class ExplodedArchive extends Archive { private Manifest manifest; - private boolean recursive = true; + private boolean filtered = false; /** * Create a new {@link ExplodedArchive} instance. @@ -78,17 +78,18 @@ public class ExplodedArchive extends Archive { throw new IllegalArgumentException("Invalid source folder " + root); } this.root = root; - this.recursive = recursive; - buildEntries(root); + buildEntries(root, recursive); this.entries = Collections.unmodifiableMap(this.entries); } private ExplodedArchive(File root, Map entries) { this.root = root; + // The entries are pre-filtered + this.filtered = true; this.entries = Collections.unmodifiableMap(entries); } - private void buildEntries(File file) { + private void buildEntries(File file, boolean recursive) { if (!file.equals(this.root)) { String name = file.toURI().getPath() .substring(this.root.toURI().getPath().length()); @@ -102,9 +103,9 @@ public class ExplodedArchive extends Archive { } for (File child : files) { if (!SKIPPED_NAMES.contains(child.getName())) { - if (file.equals(this.root) || this.recursive + if (file.equals(this.root) || recursive || file.getName().equals("META-INF")) { - buildEntries(child); + buildEntries(child, recursive); } } } @@ -113,7 +114,8 @@ public class ExplodedArchive extends Archive { @Override public URL getUrl() throws MalformedURLException { - FilteredURLStreamHandler handler = new FilteredURLStreamHandler(); + FilteredURLStreamHandler handler = this.filtered ? new FilteredURLStreamHandler() + : null; return new URL("file", "", -1, this.root.toURI().getPath(), handler); } diff --git a/spring-boot-tools/spring-boot-loader/src/test/java/org/springframework/boot/loader/archive/ExplodedArchiveTests.java b/spring-boot-tools/spring-boot-loader/src/test/java/org/springframework/boot/loader/archive/ExplodedArchiveTests.java index d9a2749c02..03c1f21ca5 100644 --- a/spring-boot-tools/spring-boot-loader/src/test/java/org/springframework/boot/loader/archive/ExplodedArchiveTests.java +++ b/spring-boot-tools/spring-boot-loader/src/test/java/org/springframework/boot/loader/archive/ExplodedArchiveTests.java @@ -147,6 +147,7 @@ public class ExplodedArchiveTests { new URL[] { filteredArchive.getUrl() }); assertThat(classLoader.getResourceAsStream("1.dat").read(), equalTo(1)); assertThat(classLoader.getResourceAsStream("2.dat"), nullValue()); + classLoader.close(); } @Test @@ -173,6 +174,25 @@ public class ExplodedArchiveTests { assertThat(entries.size(), equalTo(3)); } + @Test + public void getResourceAsStream() throws Exception { + ExplodedArchive archive = new ExplodedArchive(new File("src/test/resources/root")); + assertNotNull(archive.getManifest()); + URLClassLoader loader = new URLClassLoader(new URL[] { archive.getUrl() }); + assertNotNull(loader.getResourceAsStream("META-INF/spring/application.xml")); + loader.close(); + } + + @Test + public void getResourceAsStreamNonRecursive() throws Exception { + ExplodedArchive archive = new ExplodedArchive( + new File("src/test/resources/root"), false); + assertNotNull(archive.getManifest()); + URLClassLoader loader = new URLClassLoader(new URL[] { archive.getUrl() }); + assertNotNull(loader.getResourceAsStream("META-INF/spring/application.xml")); + loader.close(); + } + private Map getEntriesMap(Archive archive) { Map entries = new HashMap(); for (Archive.Entry entry : archive.getEntries()) { diff --git a/spring-boot-tools/spring-boot-loader/src/test/java/org/springframework/boot/loader/jar/JarFileTests.java b/spring-boot-tools/spring-boot-loader/src/test/java/org/springframework/boot/loader/jar/JarFileTests.java index 2e096462ef..d974c8e246 100644 --- a/spring-boot-tools/spring-boot-loader/src/test/java/org/springframework/boot/loader/jar/JarFileTests.java +++ b/spring-boot-tools/spring-boot-loader/src/test/java/org/springframework/boot/loader/jar/JarFileTests.java @@ -97,6 +97,7 @@ public class JarFileTests { assertThat(urlClassLoader.getResource("special/\u00EB.dat"), notNullValue()); assertThat(urlClassLoader.getResource("d/9.dat"), notNullValue()); jarFile.close(); + urlClassLoader.close(); } @Test @@ -139,6 +140,7 @@ public class JarFileTests { URLClassLoader urlClassLoader = new URLClassLoader( new URL[] { this.jarFile.getUrl() }); assertThat(urlClassLoader.getResource("special/\u00EB.dat"), notNullValue()); + urlClassLoader.close(); } @Test