diff --git a/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/jar/JarURLConnection.java b/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/jar/JarURLConnection.java index 45da271918d..fcefabb025b 100644 --- a/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/jar/JarURLConnection.java +++ b/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/jar/JarURLConnection.java @@ -59,6 +59,8 @@ class JarURLConnection extends java.net.JarURLConnection { private static final JarEntryName EMPTY_JAR_ENTRY_NAME = new JarEntryName(""); + private static final String FILE_COLON_DOUBLE_SLASH = "file://"; + private static ThreadLocal useFastExceptions = new ThreadLocal(); private final JarFile jarFile; @@ -73,7 +75,8 @@ class JarURLConnection extends java.net.JarURLConnection { // What we pass to super is ultimately ignored super(EMPTY_JAR_URL); this.url = url; - String spec = url.getFile().substring(jarFile.getUrl().getFile().length()); + String spec = getNormalizedFile(url) + .substring(jarFile.getUrl().getFile().length()); int separator; while ((separator = spec.indexOf(SEPARATOR)) > 0) { jarFile = getNestedJarFile(jarFile, spec.substring(0, separator)); @@ -83,6 +86,13 @@ class JarURLConnection extends java.net.JarURLConnection { this.jarEntryName = getJarEntryName(spec); } + private String getNormalizedFile(URL url) { + if (!url.getFile().startsWith(FILE_COLON_DOUBLE_SLASH)) { + return url.getFile(); + } + return "file:" + url.getFile().substring(FILE_COLON_DOUBLE_SLASH.length()); + } + private JarFile getNestedJarFile(JarFile jarFile, String name) throws IOException { JarEntry jarEntry = jarFile.getJarEntry(name); if (jarEntry == null) { 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 9386b7877a2..cc6eb8f2e2d 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 @@ -313,8 +313,18 @@ public class JarFileTests { @Test public void createNonNestedUrlFromString() throws Exception { + nonNestedJarFileFromString( + "jar:file:" + this.rootJarFile.getAbsolutePath() + "!/2.dat"); + } + + @Test + public void createNonNestedUrlFromStringWithDoubleSlash() throws Exception { + nonNestedJarFileFromString( + "jar:file://" + this.rootJarFile.getAbsolutePath() + "!/2.dat"); + } + + private void nonNestedJarFileFromString(String spec) throws Exception { JarFile.registerUrlProtocolHandler(); - String spec = "jar:" + this.rootJarFile.toURI() + "!/2.dat"; URL url = new URL(spec); assertThat(url.toString()).isEqualTo(spec); InputStream inputStream = url.openStream();