部署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
相关产品推荐
相关产品推荐

