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 5be57a0a381..569594e6c1f 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 @@ -28,7 +28,7 @@ import org.springframework.boot.loader.util.AsciiBytes; /** * {@link java.net.JarURLConnection} used to support {@link JarFile#getUrl()}. - * + * * @author Phillip Webb */ class JarURLConnection extends java.net.JarURLConnection { @@ -51,6 +51,7 @@ class JarURLConnection extends java.net.JarURLConnection { protected JarURLConnection(URL url, JarFile jarFile) throws MalformedURLException { super(new URL(buildRootUrl(jarFile))); + this.url = url; this.jarFile = jarFile; String spec = url.getFile(); @@ -59,27 +60,19 @@ class JarURLConnection extends java.net.JarURLConnection { throw new MalformedURLException("no " + SEPARATOR + " found in url spec:" + spec); } - /* - * The superclass constructor creates a jarFileUrl which is equal to the root URL - * of the containing archive (therefore not unique if we are connecting to - * multiple nested jars in the same archive). Therefore we need to make something - * sensible for #getJarFileURL(). - */ - if (separator + SEPARATOR.length() != spec.length()) { + if (separator + 2 != spec.length()) { this.jarEntryName = decode(spec.substring(separator + 2)); - this.jarFileUrl = new URL("jar:" + spec.substring(0, separator) + SEPARATOR - + this.jarEntryName); + } + + String container = spec.substring(0, separator); + if (container.indexOf(SEPARATOR) == -1) { + this.jarFileUrl = new URL(container); } else { - this.jarFileUrl = new URL("jar:" + spec.substring(0, separator)); + this.jarFileUrl = new URL("jar:" + container); } } - @Override - public URL getJarFileURL() { - return this.jarFileUrl; - } - @Override public void connect() throws IOException { if (this.jarEntryName != null) { @@ -108,12 +101,22 @@ class JarURLConnection extends java.net.JarURLConnection { return this.jarFile; } + @Override + public URL getJarFileURL() { + return this.jarFileUrl; + } + @Override public JarEntry getJarEntry() throws IOException { connect(); return (this.jarEntryData == null ? null : this.jarEntryData.asJarEntry()); } + @Override + public String getEntryName() { + return this.jarEntryName; + } + @Override public InputStream getInputStream() throws IOException { connect(); 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 ea4ecfba5d8..1cdf36c0661 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 @@ -183,7 +183,7 @@ public class JarFileTests { assertThat(jarURLConnection.getContentLength(), greaterThan(1)); assertThat(jarURLConnection.getContent(), sameInstance((Object) this.jarFile)); assertThat(jarURLConnection.getContentType(), equalTo("x-java/jar")); - assertThat(jarURLConnection.getJarFileURL().toString(), equalTo("jar:file:" + assertThat(jarURLConnection.getJarFileURL().toString(), equalTo("file:" + this.rootJarFile)); } @@ -296,6 +296,27 @@ public class JarFileTests { InputStream inputStream = url.openStream(); assertThat(inputStream, notNullValue()); assertThat(inputStream.read(), equalTo(3)); + JarURLConnection connection = (JarURLConnection) url.openConnection(); + assertThat(connection.getURL().toString(), equalTo(spec)); + assertThat(connection.getJarFileURL().toString(), equalTo("jar:file:" + + this.rootJarFile.getPath() + "!/nested.jar")); + assertThat(connection.getEntryName(), equalTo("3.dat")); + } + + @Test + public void createNonNestedUrlFromString() throws Exception { + JarFile.registerUrlProtocolHandler(); + String spec = "jar:file:" + this.rootJarFile.getPath() + "!/2.dat"; + URL url = new URL(spec); + assertThat(url.toString(), equalTo(spec)); + InputStream inputStream = url.openStream(); + assertThat(inputStream, notNullValue()); + assertThat(inputStream.read(), equalTo(2)); + JarURLConnection connection = (JarURLConnection) url.openConnection(); + assertThat(connection.getURL().toString(), equalTo(spec)); + assertThat(connection.getJarFileURL().toString(), equalTo("file:" + + this.rootJarFile.getPath())); + assertThat(connection.getEntryName(), equalTo("2.dat")); } @Test