Spring Boot 应用程序的 .jar 无法正常工作(tomcat-embed-jasper 问题)

Jon*_*son 4 java tomcat jar maven

我对 Spring boot 和 Maven 相当陌生。我在尝试运行可执行文件 .jar 时遇到问题。我的最终目标是创建 .jar 的 docker 映像,以便我可以部署我的应用程序。

当我执行 mvn clean install 时,我得到了应用程序的 .jar,但是当我尝试执行该 .jar 时,出现此错误:

2022-12-25T13:11:48.421+02:00 ERROR 11132 --- [           main] o.s.boot.SpringApplication               : Application run failed

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.0.jar!/:3.0.0]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:578) ~[spring-context-6.0.2.jar!/:6.0.2]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[spring-boot-3.0.0.jar!/:3.0.0]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:730) ~[spring-boot-3.0.0.jar!/:3.0.0]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:432) ~[spring-boot-3.0.0.jar!/:3.0.0]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:308) ~[spring-boot-3.0.0.jar!/:3.0.0]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1302) ~[spring-boot-3.0.0.jar!/:3.0.0]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1291) ~[spring-boot-3.0.0.jar!/:3.0.0]
    at fi.jonij.portfoliobackend.PortfolioBackendApplication.main(PortfolioBackendApplication.java:13) ~[classes!/:0.0.1-SNAPSHOT]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
    at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:49) ~[portfolio-backend.jar:0.0.1-SNAPSHOT]
    at org.springframework.boot.loader.Launcher.launch(Launcher.java:95) ~[portfolio-backend.jar:0.0.1-SNAPSHOT]
    at org.springframework.boot.loader.Launcher.launch(Launcher.java:58) ~[portfolio-backend.jar:0.0.1-SNAPSHOT]
    at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:65) ~[portfolio-backend.jar:0.0.1-SNAPSHOT]
Caused by: org.springframework.boot.web.server.WebServerException: Unable to start embedded Tomcat
    at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.initialize(TomcatWebServer.java:148) ~[spring-boot-3.0.0.jar!/:3.0.0]
    at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.<init>(TomcatWebServer.java:110) ~[spring-boot-3.0.0.jar!/:3.0.0]
    at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getTomcatWebServer(TomcatServletWebServerFactory.java:486) ~[spring-boot-3.0.0.jar!/:3.0.0]
    at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getWebServer(TomcatServletWebServerFactory.java:210) ~[spring-boot-3.0.0.jar!/:3.0.0]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.createWebServer(ServletWebServerApplicationContext.java:183) ~[spring-boot-3.0.0.jar!/:3.0.0]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:161) ~[spring-boot-3.0.0.jar!/:3.0.0]
    ... 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:938) ~[tomcat-embed-core-10.1.1.jar!/:na]
    at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:252) ~[tomcat-embed-core-10.1.1.jar!/:na]
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) ~[tomcat-embed-core-10.1.1.jar!/:na]
    at org.apache.catalina.core.StandardService.startInternal(StandardService.java:432) ~[tomcat-embed-core-10.1.1.jar!/:na]
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) ~[tomcat-embed-core-10.1.1.jar!/:na]
    at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:926) ~[tomcat-embed-core-10.1.1.jar!/:na]
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) ~[tomcat-embed-core-10.1.1.jar!/:na]
    at org.apache.catalina.startup.Tomcat.start(Tomcat.java:485) ~[tomcat-embed-core-10.1.1.jar!/:na]
    at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.initialize(TomcatWebServer.java:129) ~[spring-boot-3.0.0.jar!/:3.0.0]
    ... 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:926) ~[tomcat-embed-core-10.1.1.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:938) ~[tomcat-embed-core-10.1.1.jar!/:na]
    at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:886) ~[tomcat-embed-core-10.1.1.jar!/:na]
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) ~[tomcat-embed-core-10.1.1.jar!/:na]
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1396) ~[tomcat-embed-core-10.1.1.jar!/:na]
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1386) ~[tomcat-embed-core-10.1.1.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.1.jar!/:na]
    at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:145) ~[na:na]
    at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:919) ~[tomcat-embed-core-10.1.1.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:926) ~[tomcat-embed-core-10.1.1.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.1.jar!/:na]
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:198) ~[tomcat-embed-core-10.1.1.jar!/:na]
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1396) ~[tomcat-embed-core-10.1.1.jar!/:na]
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1386) ~[tomcat-embed-core-10.1.1.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.1.jar!/:na]
    at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:145) ~[na:na]
    at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:919) ~[tomcat-embed-core-10.1.1.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.1.jar!/:na]
    at org.apache.tomcat.util.scan.JarFactory.newInstance(JarFactory.java:41) ~[tomcat-embed-core-10.1.1.jar!/:na]
    at org.apache.tomcat.util.scan.StandardJarScanner.process(StandardJarScanner.java:393) ~[tomcat-embed-core-10.1.1.jar!/:na]
    at org.apache.tomcat.util.scan.StandardJarScanner.processURLs(StandardJarScanner.java:328) ~[tomcat-embed-core-10.1.1.jar!/:na]
    at org.apache.tomcat.util.scan.StandardJarScanner.doScanClassPath(StandardJarScanner.java:271) ~[tomcat-embed-core-10.1.1.jar!/:na]
    at org.apache.tomcat.util.scan.StandardJarScanner.scan(StandardJarScanner.java:234) ~[tomcat-embed-core-10.1.1.jar!/:na]
    at org.apache.jasper.servlet.TldScanner.scanJars(TldScanner.java:262) ~[tomcat-embed-jasper-10.1.1.jar!/:na]
    at org.apache.jasper.servlet.TldScanner.scan(TldScanner.java:104) ~[tomcat-embed-jasper-10.1.1.jar!/:na]
    at org.apache.jasper.servlet.JasperInitializer.onStartup(JasperInitializer.java:83) ~[tomcat-embed-jasper-10.1.1.jar!/:na]
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5153) ~[tomcat-embed-core-10.1.1.jar!/:na]
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) ~[tomcat-embed-core-10.1.1.jar!/:na]
    ... 43 common frames omitted


Process finished with exit code 1

Run Code Online (Sandbox Code Playgroud)

当我使用 IntelliJ 运行该应用程序时,该应用程序运行良好。如果我删除 tomcat-embed-jasper 的依赖项,.jar 也会运行良好。但是,然后我只能访问我的 spring security 默认登录页面,因为我的所有页面都是 JSP,因此我需要 tomcat-embed-jasper 来呈现这些页面。

这是我的 pom.xml:

    <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">    <modelVersion>4.0.0</modelVersion>    <parent>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-parent</artifactId>
          <version>3.0.0</version>
          <relativePath/> <!-- lookup parent from repository -->    </parent>    <groupId>fi.jonij</groupId>    <artifactId>portfolio-backend</artifactId>    <version>0.0.1-SNAPSHOT</version>    <name>portfolio-backend</name>    <description>portfolio-backend</description>    <properties>
          <java.version>17</java.version>    </properties>    <dependencies>
          <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-data-jpa</artifactId>
             <version>3.0.0</version>
          </dependency>
          <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-security</artifactId>
             <version>3.0.0</version>
          </dependency>
          <dependency>
             <groupId>commons-io</groupId>
             <artifactId>commons-io</artifactId>
             <version>2.11.0</version>
          </dependency>
          <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-web</artifactId>
             <version>3.0.0</version>
          </dependency>
          <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-data-rest</artifactId>
             <version>3.0.0</version>
          </dependency>
          <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-configuration-processor</artifactId>
             <version>3.0.0</version>
             <optional>true</optional>
          </dependency>
          <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-tomcat</artifactId>
             <scope>provided</scope>
          </dependency>
          <dependency>
             <groupId>org.apache.tomcat.embed</groupId>
             <artifactId>tomcat-embed-jasper</artifactId>
             <version>10.1.1</version>
             <scope>provided</scope>
          </dependency>
          <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-validation</artifactId>
             <version>3.0.0</version>
          </dependency>
          <dependency>
             <groupId>org.eclipse.jetty</groupId>
             <artifactId>glassfish-jstl</artifactId>
             <version>11.0.12</version>
          </dependency>
          <dependency>
             <groupId>mysql</groupId>
             <artifactId>mysql-connector-java</artifactId>
             <version>8.0.31</version>
          </dependency>
          <dependency>
             <groupId>org.webjars</groupId>
             <artifactId>bootstrap</artifactId>
             <version>5.2.3</version>
          </dependency>
          <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-devtools</artifactId>
             <version>3.0.0</version>
             <scope>runtime</scope>
             <optional>true</optional>
          </dependency>
          <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-test</artifactId>
             <version>3.0.0</version>
             <scope>test</scope>
          </dependency>
          <dependency>
             <groupId>org.springframework.security</groupId>
             <artifactId>spring-security-test</artifactId>
             <version>6.0.0</version>
             <scope>test</scope>
          </dependency>    </dependencies>
    
       <build>
          <plugins>
             <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
             </plugin>
          </plugins>
          <finalName>portfolio-backend</finalName>    </build>
    
    </project>
Run Code Online (Sandbox Code Playgroud)

我已经尝试将依赖项的范围从提供的更改为编译,反之亦然。我还检查了 org.apache.tomcat.embed 中的 spring-boot-starter-tomcat 和 tomcat-embed-jasper 中的 tomcat 版本是否正确。

我还尝试了不同的 Maven 命令,例如 mvn clean package 和 mvn -U clean install。

我还尝试禁用 tomcat 扫描 jar,这也破坏了 JSP 的渲染。

我可能会遗漏一些明显的东西,因为我对 Maven 和 Spring boot 还很陌生。如果有人可以分享这里可能存在的问题,我将不胜感激。提前致谢!:)

Pro*_*ero 5

我遇到了完全相同的问题(java -jar myWarFile.war 生成与您相​​同的错误堆栈)。目前我还没有找到解决办法,只有以下解决方法:

  1. 将war文件解压到自己的文件夹中
  2. 要运行该应用程序,请在此文件夹中打开命令行并键入以下内容:
java org/springframework/boot/loader/WarLauncher
Run Code Online (Sandbox Code Playgroud)

另外,我做了以下调查,但都是徒劳:

  • 我检查了 war 文件中的每个 jar 文件,没有一个已损坏
  • 我尝试了不同版本的Maven,同样的问题
  • 我能够使用以下命令从我的开发环境 (Eclipse) 和命令行运行该应用程序:
mvn -o spring-boot:run 
Run Code Online (Sandbox Code Playgroud)
  • 我尝试使用 jar 命令或 7zip 手动重新创建 war 文件:同样的问题

其中一个 JAR 的代码可能有问题,可能与 Spring 或 Tomcat 相关。

  • 顺便说一句,这个问题在 GitHub 上已有一个问题:https://github.com/spring-projects/spring-boot/issues/33633 (3认同)
  • 我确认问题来自tomcat-embed-jasper。我尝试过不同版本的 jasper 和 Tomcat,但它不起作用(抱歉,我无法对您的其他答案添加评论或对您的答案进行投票,没有足够的声誉:))。我希望他们能够纠正这个问题,因为它使得无法在 Spring Boot 3 和 Tomcat 中使用 JSP 页面。另外,我还没有尝试过 Jetty。 (2认同)