You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

部署Vaadin WAR至Apache Server时遇javax/servlet/ServletContainerInitializer缺失错误

问题:部署WAR包时出现javax/servlet/ServletContainerInitializer找不到的错误

环境:Vaadin 24.2.3、Java 21、Spring Boot 3.0.5、Apache Tomcat 10
部署WAR包时抛出错误:

java.lang.NoClassDefFoundError: javax/servlet/ServletContainerInitializer

所用版本均已切换至jakarta命名空间,却仍出现javax类引用问题。

项目POM文件

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <!-- Project from https://start.vaadin.com/project/e19d7d7f-cd4a-427d-814f-eccc10f31ea2 -->
    <groupId>org.mrpc</groupId>
    <artifactId>mrpc-admin</artifactId>
    <name>mrpc-admin</name>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <properties>
        <java.version>19</java.version>
        <vaadin.version>24.2.3</vaadin.version>
        <selenium.version>4.8.3</selenium.version>
    </properties>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.0.5</version>
    </parent>

    <repositories>
        <repository>
            <id>Vaadin Directory</id>
            <url>https://maven.vaadin.com/vaadin-addons</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.vaadin</groupId>
                <artifactId>vaadin-bom</artifactId>
                <version>${vaadin.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>com.vaadin</groupId>
            <!-- Replace artifactId with vaadin-core to use only free components -->
            <artifactId>vaadin</artifactId>
        </dependency>
        <dependency>
            <groupId>com.vaadin</groupId>
            <artifactId>vaadin-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.parttio</groupId>
            <artifactId>line-awesome</artifactId>
            <version>1.1.0</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.vaadin</groupId>
            <artifactId>vaadin-testbench-junit5</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.mrpc</groupId>
            <artifactId>CommonUtilities</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

    <build>
        <defaultGoal>spring-boot:run</defaultGoal>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <jvmArguments>-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5796</jvmArguments>
                    <wait>500</wait>
                    <maxAttempts>240</maxAttempts>
                </configuration>
            </plugin>

            <plugin>
                <groupId>com.vaadin</groupId>
                <artifactId>vaadin-maven-plugin</artifactId>
                <version>${vaadin.version}</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>prepare-frontend</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

    <profiles>
        <profile>
            <!-- Production mode is activated using -Pproduction -->
            <id>production</id>
            <dependencies>
                <!-- Exclude development dependencies from production -->
                <dependency>
                    <groupId>com.vaadin</groupId>
                    <artifactId>vaadin-core</artifactId>
                    <exclusions>
                        <exclusion>
                            <groupId>com.vaadin</groupId>
                            <artifactId>vaadin-dev</artifactId>
                        </exclusion>
                    </exclusions>
                </dependency>
            </dependencies>
            <build>
                <plugins>
                    <plugin>
                        <groupId>com.vaadin</groupId>
                        <artifactId>vaadin-maven-plugin</artifactId>
                        <version>${vaadin.version}</version>
                        <executions>
                            <execution>
                                <goals>
                                    <goal>build-frontend</goal>
                                </goals>
                                <phase>compile</phase>
                            </execution>
                        </executions>
                    </plugin>
                </plugins>
            </build>
        </profile>

        <profile>
            <id>it</id>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.springframework.boot</groupId>
                        <artifactId>spring-boot-maven-plugin</artifactId>
                        <executions>
                            <execution>
                                <id>start-spring-boot</id>
                                <phase>pre-integration-test</phase>
                                <goals>
                                    <goal>start</goal>
                                </goals>
                            </execution>
                            <execution>
                                <id>stop-spring-boot</id>
                                <phase>post-integration-test</phase>
                                <goals>
                                    <goal>stop</goal>
                                </goals>
                            </execution>
                        </executions>
                    </plugin>

                    <!-- Runs the integration tests (*IT) after the server is started -->
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-failsafe-plugin</artifactId>
                        <executions>
                            <execution>
                                <goals>
                                    <goal>integration-test</goal>
                                    <goal>verify</goal>
                                </goals>
                            </execution>
                        </executions>
                        <configuration>
                            <trimStackTrace>false</trimStackTrace>
                            <enableAssertions>true</enableAssertions>
                        </configuration>
                    </plugin>
                </plugins>
            </build>
        </profile>

    </profiles>
</project>

堆栈跟踪信息

19-Dec-2023 16:15:49.515 SEVERE [Catalina-utility-2] org.apache.catalina.startup.HostConfig.deployWAR Error deploying web application archive [D:\Tomcat10.1\webapps\mrpc-admin-1.0-SNAPSHOT.war]
        java.lang.IllegalStateException: Error starting child
                at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:686)
                at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:658)
                at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:712)
                at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:975)
                at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1952)
                at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572)
                at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
                at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
                at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:123)
                at org.apache.catalina.startup.HostConfig.deployWARs(HostConfig.java:776)
                at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:426)
                at org.apache.catalina.startup.HostConfig.check(HostConfig.java:1708)
                at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:305)
                at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:114)
                at org.apache.catalina.core.ContainerBase.backgroundProcess(ContainerBase.java:1098)
                at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1301)
                at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1305)
                at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1283)
                at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572)
                at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:358)
                at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305)
                at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
                at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
                at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
                at java.base/java.lang.Thread.run(Thread.java:1583)
        Caused by: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/mrpc-admin-1.0-SNAPSHOT]]
                at org.apache.catalina.util.LifecycleBase.handleSubClassException(LifecycleBase.java:419)
                at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:186)
                at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:683)
                ... 24 more
        Caused by: java.lang.NoClassDefFoundError: javax/servlet/ServletContainerInitializer
                at java.base/java.lang.ClassLoader.defineClass1(Native Method)
                at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1027)
                at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:150)
                at org.apache.catalina.loader.WebappClassLoaderBase.findClassInternal(WebappClassLoaderBase.java:2352)
                at org.apache.catalina.loader.WebappClassLoaderBase.findClass(WebappClassLoaderBase.java:800)
                at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1317)
                at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1165)
                at java.base/java.lang.Class.forName0(Native Method)
                at java.base/java.lang.Class.forName(Class.java:534)
                at java.base/java.lang.Class.forName(Class.java:513)
                at org.apache.catalina.startup.WebappServiceLoader.loadServices(WebappServiceLoader.java:235)
                at org.apache.catalina.startup.WebappServiceLoader.load(WebappServiceLoader.java:206)
                at org.apache.catalina.startup.ContextConfig.processServletContainerInitializers(ContextConfig.java:1838)
                at org.apache.catalina.startup.ContextConfig.webConfig(ContextConfig.java:1303)
                at org.apache.catalina.startup.ContextConfig.configureStart(ContextConfig.java:991)
                at org.apache.catalina.startup.ContextConfig.lifecycleEvent(ContextConfig.java:304)
                at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:114)
                at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:4766)
                at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:171)
                ... 25 more
        Caused by: java.lang.ClassNotFoundException: javax.servlet.ServletContainerInitializer
                at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1353)
                at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1165)
                ... 44 more

解决方案

1. 重点排查自定义依赖CommonUtilities

这是最可能的问题源头:

  • 该自定义依赖大概率仍依赖javax.servlet相关类,未切换到jakarta
  • 执行mvn dependency:tree查看依赖树,确认该包是否间接引入了javax.servlet的jar
  • 解决办法:
    • 升级CommonUtilities到适配jakarta命名空间的版本
    • 若无法升级,在POM中排除该依赖的javax相关传递依赖:
      <dependency>
          <groupId>org.mrpc</groupId>
          <artifactId>CommonUtilities</artifactId>
          <version>1.0-SNAPSHOT</version>
          <exclusions>
              <exclusion>
                  <groupId>javax.servlet</groupId>
                  <artifactId>*</artifactId>
              </exclusion>
          </exclusions>
      </dependency>
      

2. 统一Java版本配置

POM中java.version设为19,但实际使用Java 21,修改为一致:

<properties>
    <java.version>21</java.version>
    <!-- 其他属性保留不变 -->
</properties>

3. 验证WAR包依赖

执行mvn clean package -Pproduction构建生产包后,检查WEB-INF/lib目录:

  • 确保没有javax.servlet-api.jar或其他带javax命名空间的jar包
  • 若存在,通过依赖排除移除

4. 确认Tomcat配置

Tomcat 10.x本身适配jakarta,无需额外配置,但需确保:

  • Tomcat安装目录下的lib中没有遗留的javax.servlet相关jar
  • 项目未手动引入任何javax.servlet的依赖

内容的提问来源于stack exchange,提问作者Todd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 18:43:09