diff --git a/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/jar/JarFile.java b/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/jar/JarFile.java index 7a3ee76a4ff..162395c295b 100644 --- a/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/jar/JarFile.java +++ b/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/jar/JarFile.java @@ -371,6 +371,10 @@ public class JarFile extends java.util.jar.JarFile { return this.pathFromRoot; } + JarFileType getType() { + return this.type; + } + /** * Register a {@literal 'java.protocol.handler.pkgs'} property so that a * {@link URLStreamHandler} will be located to deal with jar URLs. @@ -396,7 +400,10 @@ public class JarFile extends java.util.jar.JarFile { } } - private enum JarFileType { + /** + * The type of a {@link JarFile}. + */ + enum JarFileType { DIRECT, NESTED_DIRECTORY, NESTED_JAR } 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 ca2ff46c16a..7f2b5ce6ed2 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 @@ -29,6 +29,8 @@ import java.net.URLEncoder; import java.net.URLStreamHandler; import java.security.Permission; +import org.springframework.boot.loader.data.RandomAccessData.ResourceAccess; + /** * {@link java.net.JarURLConnection} used to support {@link JarFile#getUrl()}. * @@ -160,11 +162,14 @@ final class JarURLConnection extends java.net.JarURLConnection { if (this.jarFile == null) { throw FILE_NOT_FOUND_EXCEPTION; } - if (this.jarEntryName.isEmpty()) { + if (this.jarEntryName.isEmpty() + && this.jarFile.getType() == JarFile.JarFileType.DIRECT) { throw new IOException("no entry name specified"); } connect(); - InputStream inputStream = this.jarFile.getInputStream(this.jarEntry); + InputStream inputStream = (this.jarEntryName.isEmpty() + ? this.jarFile.getData().getInputStream(ResourceAccess.ONCE) + : this.jarFile.getInputStream(this.jarEntry)); if (inputStream == null) { throwFileNotFound(this.jarEntryName, this.jarFile); } 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 f4cc67b9ff8..d9e29934004 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 @@ -28,6 +28,7 @@ import java.net.URLClassLoader; import java.nio.charset.Charset; import java.util.Enumeration; import java.util.jar.JarEntry; +import java.util.jar.JarInputStream; import java.util.jar.Manifest; import java.util.zip.ZipEntry; @@ -54,6 +55,7 @@ import static org.mockito.Mockito.verify; * @author Andy Wilkinson */ public class JarFileTests { + private static final String PROTOCOL_HANDLER = "java.protocol.handler.pkgs"; private static final String HANDLERS_PACKAGE = "org.springframework.boot.loader"; @@ -270,6 +272,12 @@ public class JarFileTests { assertThat(conn.getJarFile()).isSameAs(nestedJarFile); assertThat(conn.getJarFileURL().toString()) .isEqualTo("jar:" + this.rootJarFile.toURI() + "!/nested.jar"); + assertThat(conn.getInputStream()).isNotNull(); + JarInputStream jarInputStream = new JarInputStream(conn.getInputStream()); + assertThat(jarInputStream.getNextJarEntry().getName()).isEqualTo("3.dat"); + assertThat(jarInputStream.getNextJarEntry().getName()).isEqualTo("4.dat"); + assertThat(jarInputStream.getNextJarEntry().getName()).isEqualTo("\u00E4.dat"); + jarInputStream.close(); assertThat(conn.getPermission()).isInstanceOf(FilePermission.class); FilePermission permission = (FilePermission) conn.getPermission(); assertThat(permission.getActions()).isEqualTo("read");