Skip to content

InputStreams cannot be created from nested directory entry URLs which results in Tomcat TldScanner issues #38047

@dconard

Description

@dconard

Spring Boot Version

3.2.0-RC1

Description of Bug/Issue

We use an embedded tomcat to bring up a server that still uses Java Server Pages (jsp), and still needs to scan for taglibs. This has normally not causes any issues. But when trying to migrate to Spring Boot 3.2.0, we've seen logs like these upon startup:

ZipException trying to scan `WEB-INF/classes

2023-10-25 11:55:26,387 INFO  [] org.apache.catalina.core.StandardEngine: Starting Servlet engine: [Apache Tomcat/10.1.15]
2023-10-25 11:55:26,676 WARN  [] org.apache.tomcat.util.scan.StandardJarScanner: Failed to scan [jar:nested:/Users/dconard/projects/web/backend/app/build/libs/app.war/!WEB-INF/classes/!/] from classloader hierarchy
java.util.zip.ZipException: invalid entry size (expected 2531524616 but got 0 bytes)
	at java.base/java.util.zip.ZipInputStream.readEnd(ZipInputStream.java:399)
	at java.base/java.util.zip.ZipInputStream.read(ZipInputStream.java:198)
	at java.base/java.util.jar.JarInputStream.read(JarInputStream.java:194)
	at java.base/java.util.zip.ZipInputStream.closeEntry(ZipInputStream.java:142)
	at java.base/java.util.zip.ZipInputStream.getNextEntry(ZipInputStream.java:120)
	at java.base/java.util.jar.JarInputStream.<init>(JarInputStream.java:84)
	at java.base/java.util.jar.JarInputStream.<init>(JarInputStream.java:61)
	at org.apache.tomcat.util.scan.NonClosingJarInputStream.<init>(NonClosingJarInputStream.java:37)
	at org.apache.tomcat.util.scan.UrlJar.createJarInputStream(UrlJar.java:47)
	at org.apache.tomcat.util.scan.AbstractInputStreamJar.reset(AbstractInputStreamJar.java:160)
	at org.apache.tomcat.util.scan.AbstractInputStreamJar.getManifest(AbstractInputStreamJar.java:151)
	at org.apache.tomcat.util.scan.StandardJarScanner.processManifest(StandardJarScanner.java:444)
	at org.apache.tomcat.util.scan.StandardJarScanner.process(StandardJarScanner.java:399)
	at org.apache.tomcat.util.scan.StandardJarScanner.processURLs(StandardJarScanner.java:332)
	at org.apache.tomcat.util.scan.StandardJarScanner.doScanClassPath(StandardJarScanner.java:275)
	at org.apache.tomcat.util.scan.StandardJarScanner.scan(StandardJarScanner.java:238)
	at org.apache.jasper.servlet.TldScanner.scanJars(TldScanner.java:262)
	at org.apache.jasper.servlet.TldScanner.scan(TldScanner.java:104)
	at org.apache.jasper.servlet.JasperInitializer.onStartup(JasperInitializer.java:83)

Failure to scan jars

2023-10-25 11:55:26,686 WARN  [] org.apache.tomcat.util.scan.StandardJarScanner: Failed to scan [jar:nested:/Users/dconard/projects/web/backend/app/build/libs/app.war/!WEB-INF/lib/jakarta.servlet.jsp.jstl-3.0.1.jar!/] from classloader hierarchy
java.io.IOException: no entry name specified
	at org.springframework.boot.loader.net.protocol.jar.JarUrlConnection.getInputStream(JarUrlConnection.java:179)
	at org.apache.catalina.webresources.war.WarURLConnection.getInputStream(WarURLConnection.java:52)
	at java.base/java.net.URL.openStream(URL.java:1161)
	at org.springframework.boot.loader.net.protocol.jar.UrlJarFileFactory.createJarFileForStream(UrlJarFileFactory.java:89)
	at org.springframework.boot.loader.net.protocol.jar.UrlJarFileFactory.createJarFile(UrlJarFileFactory.java:57)
	at org.springframework.boot.loader.net.protocol.jar.UrlJarFiles.getOrCreate(UrlJarFiles.java:72)
	at org.springframework.boot.loader.net.protocol.jar.JarUrlConnection.connect(JarUrlConnection.java:277)
	at org.springframework.boot.loader.net.protocol.jar.JarUrlConnection.getInputStream(JarUrlConnection.java:189)
	at java.base/java.net.URL.openStream(URL.java:1161)
	at org.apache.tomcat.util.descriptor.tld.TldResourcePath.openStream(TldResourcePath.java:127)
	at org.apache.tomcat.util.descriptor.tld.TldParser.parse(TldParser.java:62)
	at org.apache.jasper.servlet.TldScanner.parseTld(TldScanner.java:275)
2023-10-25 11:55:26,718 WARN  [] org.apache.tomcat.util.scan.StandardJarScanner: Failed to scan [jar:nested:/Users/dconard/projects/web/backend/app/build/libs/app.war/!WEB-INF/lib/spring-webmvc-6.1.0-RC1.jar!/] from classloader hierarchy
java.io.IOException: no entry name specified
	at org.springframework.boot.loader.net.protocol.jar.JarUrlConnection.getInputStream(JarUrlConnection.java:179)
	at org.apache.catalina.webresources.war.WarURLConnection.getInputStream(WarURLConnection.java:52)
	at java.base/java.net.URL.openStream(URL.java:1161)
	at org.springframework.boot.loader.net.protocol.jar.UrlJarFileFactory.createJarFileForStream(UrlJarFileFactory.java:89)
	at org.springframework.boot.loader.net.protocol.jar.UrlJarFileFactory.createJarFile(UrlJarFileFactory.java:57)
	at org.springframework.boot.loader.net.protocol.jar.UrlJarFiles.getOrCreate(UrlJarFiles.java:72)
	at org.springframework.boot.loader.net.protocol.jar.JarUrlConnection.connect(JarUrlConnection.java:277)
	at org.springframework.boot.loader.net.protocol.jar.JarUrlConnection.getInputStream(JarUrlConnection.java:189)
	at java.base/java.net.URL.openStream(URL.java:1161)
	at org.apache.tomcat.util.descriptor.tld.TldResourcePath.openStream(TldResourcePath.java:127)
	at org.apache.tomcat.util.descriptor.tld.TldParser.parse(TldParser.java:62)
	at org.apache.jasper.servlet.TldScanner.parseTld(TldScanner.java:275)
2023-10-25 11:55:26,725 WARN  [] org.apache.tomcat.util.scan.StandardJarScanner: Failed to scan [jar:nested:/Users/dconard/projects/web/backend/app/build/libs/app.war/!WEB-INF/lib/struts-taglib-1.3.8.jar!/] from classloader hierarchy
java.io.IOException: no entry name specified
	at org.springframework.boot.loader.net.protocol.jar.JarUrlConnection.getInputStream(JarUrlConnection.java:179)
	at org.apache.catalina.webresources.war.WarURLConnection.getInputStream(WarURLConnection.java:52)
	at java.base/java.net.URL.openStream(URL.java:1161)
	at org.springframework.boot.loader.net.protocol.jar.UrlJarFileFactory.createJarFileForStream(UrlJarFileFactory.java:89)
	at org.springframework.boot.loader.net.protocol.jar.UrlJarFileFactory.createJarFile(UrlJarFileFactory.java:57)
	at org.springframework.boot.loader.net.protocol.jar.UrlJarFiles.getOrCreate(UrlJarFiles.java:72)
	at org.springframework.boot.loader.net.protocol.jar.JarUrlConnection.connect(JarUrlConnection.java:277)
	at org.springframework.boot.loader.net.protocol.jar.JarUrlConnection.getInputStream(JarUrlConnection.java:189)
	at java.base/java.net.URL.openStream(URL.java:1161)
	at org.apache.tomcat.util.descriptor.tld.TldResourcePath.openStream(TldResourcePath.java:127)
	at org.apache.tomcat.util.descriptor.tld.TldParser.parse(TldParser.java:62)
	at org.apache.jasper.servlet.TldScanner.parseTld(TldScanner.java:275)

The documentation here mentioned that the loaderImplementation has changed. I was able to resolve the issue by changing to the CLASSIC implementation. But I wanted to raise an issue posterity's sake.

Metadata

Metadata

Assignees

Labels

type: regressionA regression from a previous release

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions