Docker构建Maven项目后运行报java.lang.NoClassDefFoundError求助
Maven项目Docker化运行报错:NoClassDefFoundError: org/apache/catalina/WebResourceRoot
问题背景
尝试将Maven项目Docker化,相关配置与报错信息如下:
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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>de.fhws.biedermann.webshop</groupId> <artifactId>progPorj</artifactId> <version>1.0-SNAPSHOT</version> <build> <finalName>webshop</finalName> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>3.1.0</version> <configuration> <failOnMissingWebXml>false</failOnMissingWebXml> <archive> <manifest> <addClasspath>true</addClasspath> <classpathPrefix>lib/</classpathPrefix> <mainClass>de.fhws.biedermann.webshop.Start</mainClass> </manifest> </archive> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> </configuration> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.4</version> <scope>test</scope> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> <scope>provided</scope> </dependency> <dependency> <groupId>com.owlike</groupId> <artifactId>genson</artifactId> <version>1.6</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-io</artifactId> <version>1.3.2</version> </dependency> <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> <dependency> <groupId>javax.ws.rs</groupId> <artifactId>javax.ws.rs-api</artifactId> <version>2.1</version> </dependency> <dependency> <groupId>org.glassfish.jersey.core</groupId> <artifactId>jersey-server</artifactId> <version>${jersey.version}</version> </dependency> <dependency> <groupId>org.glassfish.jersey.containers</groupId> <artifactId>jersey-container-servlet</artifactId> <version>${jersey.version}</version> </dependency> <dependency> <groupId>org.glassfish.jersey.containers</groupId> <artifactId>jersey-container-servlet-core</artifactId> <version>${jersey.version}</version> </dependency> <dependency> <groupId>org.glassfish.jersey.ext</groupId> <artifactId>jersey-declarative-linking</artifactId> <version>${jersey.version}</version> </dependency> <dependency> <groupId>org.glassfish.jersey.media</groupId> <artifactId>jersey-media-multipart</artifactId> <version>${jersey.version}</version> </dependency> <dependency> <groupId>com.squareup.okhttp3</groupId> <artifactId>okhttp</artifactId> <version>3.7.0</version> </dependency> <dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> <version>2.6</version> </dependency> <dependency> <groupId>org.glassfish.jersey.inject</groupId> <artifactId>jersey-hk2</artifactId> <version>${jersey.version}</version> </dependency> <dependency> <groupId>jakarta.ws.rs</groupId> <artifactId>jakarta.ws.rs-api</artifactId> <version>2.1.6</version> </dependency> <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>28.2-android</version> </dependency> <dependency> <groupId>org.xerial</groupId> <artifactId>sqlite-jdbc</artifactId> <version>3.36.0.3</version> </dependency> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-api</artifactId> <version>5.8.2</version> </dependency> <dependency> <groupId>org.json</groupId> <artifactId>json</artifactId> <version>20180130</version> </dependency> </dependencies> <properties> <maven.compiler.source>16</maven.compiler.source> <maven.compiler.target>16</maven.compiler.target> <tomcat.version>8.5.13</tomcat.version> <jersey.version>2.31</jersey.version> </properties> </project>
Dockerfile配置
# # Build stage # FROM maven:3.8.4-openjdk-17 AS build COPY . /home/app RUN mvn -f /home/app/pom.xml clean package # # Package stage # FROM openjdk:16-alpine3.13 COPY --from=build /home/app/target/webshop.jar /usr/local/lib/webshop.jar EXPOSE 8080 ENTRYPOINT ["java","-jar","/usr/local/lib/webshop.jar"]
运行报错
Error: Unable to initialize main class de.fhws.biedermann.webshop.Start Caused by: java.lang.NoClassDefFoundError: org/apache/catalina/WebResourceRoot
解决方案
问题根源
当前使用的maven-jar-plugin不支持jar-with-dependencies这个描述符,该配置属于maven-assembly-plugin。因此构建过程未将所有依赖打包到最终jar中,导致运行时找不到Tomcat相关类。
修复步骤
1. 替换Maven打包插件
修改pom.xml的build插件,使用maven-assembly-plugin构建包含所有依赖的可执行jar:
<build> <finalName>webshop</finalName> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <version>3.3.0</version> <configuration> <finalName>webshop</finalName> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> <archive> <manifest> <mainClass>de.fhws.biedermann.webshop.Start</mainClass> </manifest> </archive> </configuration> <executions> <execution> <id>make-assembly</id> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <source>16</source> <target>16</target> </configuration> </plugin> </plugins> </build>
2. 重新构建并运行
执行以下命令重新构建镜像并启动容器:
docker build -t webshop . docker run -p 8080:8080 webshop
内容的提问来源于stack exchange,提问作者Jakob Priesner
相关产品推荐
相关产品推荐

