运行廖雪峰MVC示例报错:Main类初始化失败,找不到WebResourceRoot
问题:运行嵌入式Tomcat启动类时出现NoClassDefFoundError
运行嵌入式Tomcat的Main类时,抛出如下错误:
Error: can't initialize the main class: com.itranswarp.learnjava.Main Cause:java.lang.NoClassDefFoundError:org/apache/catalina/WebResourceRoot
当前配置与代码
pom.xml 核心内容
<groupId>com.itranswarp.learnjava</groupId> <artifactId>web-mvc</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <maven.compiler.source>17</maven.compiler.source> <maven.compiler.target>17</maven.compiler.target> <java.version>17</java.version> <jackson.version>2.12.7.1</jackson.version> <pebble.version>3.1.6</pebble.version> <tomcat.version>10.1.6</tomcat.version> </properties> <dependencies> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>${jackson.version}</version> </dependency> <dependency> <groupId>io.pebbletemplates</groupId> <artifactId>pebble</artifactId> <version>${pebble.version}</version> </dependency> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-core</artifactId> <version>${tomcat.version}</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-jasper</artifactId> <version>${tomcat.version}</version> <scope>provided</scope> </dependency> </dependencies>
Main类代码
package com.itranswarp.learnjava; import org.apache.catalina.Context; import org.apache.catalina.WebResourceRoot; import org.apache.catalina.startup.Tomcat; import org.apache.catalina.webresources.DirResourceSet; import org.apache.catalina.webresources.StandardRoot; import java.io.File; public class Main { public static void main(String[] args) throws Exception { Tomcat tomcat = new Tomcat(); tomcat.setPort(Integer.getInteger("port", 8080)); tomcat.getConnector(); Context ctx = tomcat.addWebapp("", new File("src/main/webapp").getAbsolutePath()); WebResourceRoot resources = new StandardRoot(ctx); resources.addPreResources(new DirResourceSet(resources, "/WEB-INF/classes", new File("target/classes").getAbsolutePath(), "/")); ctx.setResources(resources); tomcat.start(); tomcat.getServer().await(); } }
已尝试操作:更新pom.xml中的Tomcat版本及插件、切换使用JDK17,问题未解决。
解决方案
核心原因
Tomcat嵌入依赖的<scope>provided</scope>导致运行时无法获取相关类。provided scope表示依赖仅在编译、测试阶段可用,运行时会假设由外部容器提供这些类,但这里是直接运行Main类启动嵌入式Tomcat,需要将这些依赖包含在运行环境中。
修复步骤
- 修改pom.xml中的依赖scope:
移除tomcat-embed-core和tomcat-embed-jasper的<scope>provided</scope>配置,或改为<scope>compile</scope>,修改后依赖块如下:<dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-core</artifactId> <version>${tomcat.version}</version> </dependency> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-jasper</artifactId> <version>${tomcat.version}</version> </dependency> - 重新编译项目:
执行Maven命令清理并编译:mvn clean compile - 重新运行Main类:
再次启动Main类,即可正常加载嵌入式Tomcat所需的类。
内容的提问来源于stack exchange,提问作者SpywithJava
相关产品推荐
相关产品推荐

