Ensure getResources("") includes nested root URLs
Previously, if Boot's JarURLConnection pointed to the root of a nested
entry, e.g. /BOOT-INF/classes, a call to getInputStream() would throw
an IOException. This behavior is reasonable for a URL that points
to the root of a normal jar as the jar itself is on the class path
anyway. However, for a nested jar it meant that a call to
ClassLoader.getResources("") would not include URLs for any nested
jars and directories (/BOOT-INF/classes and jars in /BOOT-INF/lib).
This is due to some logic in URLClassPath.Loader.findResource that
verifies a URL by opening a connection and calling getInputStream().
The result of missing URLs for the root of nested jars and directories
is that classpath scanning that scans from the root (not a good idea
for performance reasons, but something that we should support) would
not find entries in /BOOT-INF/classes or in jars in /BOOT-INF/lib.
This commit updates our JarURLConnection so that it no longer throws
an IOException when asked for an InputStream for the root of a nested
entry (directory or jar).
Fixes gh-7003
This commit is contained in:
committed by
Phillip Webb
parent
57d5a2ebc6
commit
cdcc3d2f28
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user