I see a similar bug described in other tickets such as #23821, but they all claim this was fixed back in 2020 in the Spring Boot 2.x line.

I have a very simple JSP/Thymeleaf Spring Boot app I haven't touched in a couple of years. I just now opened the project and updated the dependencies to the latest version, including Spring Boot 3.0.2. It uses my own root POM and imports Spring Boot:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-parent</artifactId>
  <version>3.0.2</version>
  <type>pom</type>
  <scope>import</scope>
</dependency>

The web modules makes an executable JAR:

<plugin>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-maven-plugin</artifactId>
  <executions>
    <execution>
      <goals>
        <goal>repackage</goal>
      </goals>
    </execution>
  </executions>
</plugin>

When I run it using java -jar web\target\myapp-web-1.1.0-SNAPSHOT.jar with Java 17 I get "java.lang.IllegalStateException: zip file closed", apparently when Tomcat tries to access the JAR manifest:

org.springframework.context.ApplicationContextException: Unable to start web server
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:164) ~[spring-boot-3.0.2.jar!/:3.0.2]
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:578) ~[spring-context-6.0.4.jar!/:6.0.4]
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[spring-boot-3.0.2.jar!/:3.0.2]
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:730) ~[spring-boot-3.0.2.jar!/:3.0.2]
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:432) ~[spring-boot-3.0.2.jar!/:3.0.2]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:308) ~[spring-boot-3.0.2.jar!/:3.0.2]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1302) ~[spring-boot-3.0.2.jar!/:3.0.2]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1291) ~[spring-boot-3.0.2.jar!/:3.0.2]
        [...]
Caused by: org.springframework.boot.web.server.WebServerException: Unable to start embedded Tomcat
        at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.initialize(TomcatWebServer.java:142) ~[spring-boot-3.0.2.jar!/:3.0.2]
        at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.<init>(TomcatWebServer.java:104) ~[spring-boot-3.0.2.jar!/:3.0.2]
        at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getTomcatWebServer(TomcatServletWebServerFactory.java:486) ~[spring-boot-3.0.2.jar!/:3.0.2]
        at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getWebServer(TomcatServletWebServerFactory.java:210) ~[spring-boot-3.0.2.jar!/:3.0.2]
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.createWebServer(ServletWebServerApplicationContext.java:183) ~[spring-boot-3.0.2.jar!/:3.0.2]
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:161) ~[spring-boot-3.0.2.jar!/:3.0.2]
        ... 16 common frames omitted
Caused by: org.apache.catalina.LifecycleException: A child container failed during start
        at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:935) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:252) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.catalina.core.StandardService.startInternal(StandardService.java:430) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:926) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.catalina.startup.Tomcat.start(Tomcat.java:485) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.initialize(TomcatWebServer.java:123) ~[spring-boot-3.0.2.jar!/:3.0.2]
        ... 21 common frames omitted
Caused by: java.util.concurrent.ExecutionException: org.apache.catalina.LifecycleException: A child container failed during start
        at java.base/java.util.concurrent.FutureTask.report(FutureTask.java:122) ~[na:na]
        at java.base/java.util.concurrent.FutureTask.get(FutureTask.java:191) ~[na:na]
        at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:923) ~[tomcat-embed-core-10.1.5.jar!/:na]
        ... 29 common frames omitted
Caused by: org.apache.catalina.LifecycleException: A child container failed during start
        at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:935) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:886) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1393) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1383) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) ~[na:na]
        at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:145) ~[na:na]
        at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:916) ~[tomcat-embed-core-10.1.5.jar!/:na]
        ... 29 common frames omitted
Caused by: java.util.concurrent.ExecutionException: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Tomcat].StandardHost[localhost].TomcatEmbeddedContext[]]
        at java.base/java.util.concurrent.FutureTask.report(FutureTask.java:122) ~[na:na]
        at java.base/java.util.concurrent.FutureTask.get(FutureTask.java:191) ~[na:na]
        at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:923) ~[tomcat-embed-core-10.1.5.jar!/:na]
        ... 37 common frames omitted
Caused by: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Tomcat].StandardHost[localhost].TomcatEmbeddedContext[]]
        at org.apache.catalina.util.LifecycleBase.handleSubClassException(LifecycleBase.java:440) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:198) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1393) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1383) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) ~[na:na]
        at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:145) ~[na:na]
        at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:916) ~[tomcat-embed-core-10.1.5.jar!/:na]
        ... 37 common frames omitted
Caused by: java.lang.IllegalStateException: zip file closed
        at java.base/java.util.zip.ZipFile.ensureOpen(ZipFile.java:831) ~[na:na]
        at java.base/java.util.zip.ZipFile.getManifestName(ZipFile.java:1057) ~[na:na]
        at java.base/java.util.zip.ZipFile$1.getManifestName(ZipFile.java:1100) ~[na:na]
        at java.base/java.util.jar.JarFile.getManEntry(JarFile.java:937) ~[na:na]
        at java.base/java.util.jar.JarFile.checkForSpecialAttributes(JarFile.java:1000) ~[na:na]
        at java.base/java.util.jar.JarFile.isMultiRelease(JarFile.java:389) ~[na:na]
        at org.apache.tomcat.util.scan.JarFileUrlJar.<init>(JarFileUrlJar.java:68) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.tomcat.util.scan.JarFactory.newInstance(JarFactory.java:41) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.tomcat.util.scan.StandardJarScanner.process(StandardJarScanner.java:393) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.tomcat.util.scan.StandardJarScanner.processURLs(StandardJarScanner.java:328) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.tomcat.util.scan.StandardJarScanner.doScanClassPath(StandardJarScanner.java:271) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.tomcat.util.scan.StandardJarScanner.scan(StandardJarScanner.java:234) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.jasper.servlet.TldScanner.scanJars(TldScanner.java:262) ~[tomcat-embed-jasper-10.1.5.jar!/:na]
        at org.apache.jasper.servlet.TldScanner.scan(TldScanner.java:104) ~[tomcat-embed-jasper-10.1.5.jar!/:na]
        at org.apache.jasper.servlet.JasperInitializer.onStartup(JasperInitializer.java:83) ~[tomcat-embed-jasper-10.1.5.jar!/:na]
        at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5144) ~[tomcat-embed-core-10.1.5.jar!/:na]
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) ~[tomcat-embed-core-10.1.5.jar!/:na]
        ... 43 common frames omitted

Comment From: scottfrederick

This is a duplicate of #33633.

Comment From: garretwilson

But can someone tell me what the workaround is? #33633 isn't clear at all what I need to do to make this work.

I tried downgrading to the latest Spring Boot 2.x which currently is v2.7.8, but that breaks my unit tests because Spring Boot 2.x uses an old version of the JUnit API, which produces java.lang.NoClassDefFoundError: org/junit/jupiter/api/io/CleanupMode. (See junit5/issues/2991.)

I can work around that, but then Spring Boot 2.x relies on the obsolete SLF4J StaticLoggerBinder, which has been removed in SLF4J.

What workaround is there to get this to work in Spring Boot 3?

Comment From: scottfrederick

The workaround for Spring Boot 3 is to set the system property jdk.util.jar.enableMultiRelease to false as shown in this example.

Comment From: garretwilson

But adding something to the command line defeats much of the purpose of a Spring Boot executable JAR.

You're telling me the entire Spring Boot 3 ecosystem is hobbled in this way? So if I deploy my JARs in the cloud with some orchestrator, I'll have to muck with the settings to add this special system property just to get them to run??

Comment From: garretwilson

You're telling me the entire Spring Boot 3 ecosystem is hobbled in this way? So if I deploy my JARs in the cloud with some orchestrator, I'll have to muck with the settings to add this special system property just to get them to run??

For those coming late to this ticket, I was incorrect in my understanding. In fact "the entire Spring Boot 3 ecosystem" is not "hobbled". Rather, although Spring could and should improve the code related to this issue (#32106), this particular problem currently only surfaces when JSP is being used, in particular using Tomcat Jasper. Thus it rarely occurs, and with old technology, so it has not surprisingly been given low priority. See #33633 for more details and for the status of updated documentation.

Update: This appears to have been mitigated in Tomcat, so this issue should no longer appear.

Comment From: amogh-orolabs-dev

@garretwilson thanks!