Spring Boot多阶段Docker构建依赖缺失NoClassDefFoundError问题
问题分析与解决方案
问题原因
你遇到的java.lang.NoClassDefFoundError: org/json/JSONObject错误,核心原因是app1(app-util-1.0.0.jar)作为Spring Boot可执行jar被引入时,Maven无法自动解析其内部的依赖传递。
Spring Boot默认打包的可执行jar采用特殊目录结构(依赖存放在BOOT-INF/lib),这种jar并非为作为依赖被其他项目引入设计,Maven无法从中提取app1声明的依赖(比如org.json),导致app2构建时不会自动包含这些依赖,最终运行时缺少对应类。
解决方案
方案1:修改app1的打包方式,生成可被依赖的普通jar
在app1的pom.xml中配置Spring Boot Maven插件,生成两个jar包:一个用于执行,一个用于被其他项目依赖:
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <!-- 指定可执行jar的分类器,同时生成普通可依赖jar --> <classifier>exec</classifier> </configuration> </plugin> </plugins> </build>
打包后会得到:
app-util-1.0.0.jar:普通jar,可被app2作为依赖引入,Maven能正常解析其传递依赖app-util-1.0.0-exec.jar:可执行jar,用于单独运行app1
将这个普通的app-util-1.0.0.jar放入Docker构建流程中install即可。
方案2:在app2中手动添加缺失的依赖
如果无法修改app1的打包配置,直接在app2的pom.xml中添加org.json依赖(版本需与app1中使用的一致):
<dependency> <groupId>org.json</groupId> <artifactId>json</artifactId> <version>20240303</version> <!-- 替换为app1实际依赖的版本 --> </dependency>
额外检查:Dockerfile简化优化
你的Dockerfile存在冗余步骤,可简化为:
FROM maven:3.8.4-eclipse-temurin-17 AS builder WORKDIR /app # 先安装自定义jar到本地仓库 COPY ./app-util-1.0.0.jar /tmp/ RUN mvn install:install-file \ -Dfile=/tmp/app-util-1.0.0.jar \ -DgroupId=com.app \ -DartifactId=app-util \ -Dversion=1.0.0 \ -Dpackaging=jar \ -DgeneratePom=true # 复制项目代码并构建 COPY ./ ./ RUN mvn clean package -DskipTests=true FROM eclipse-temurin:17-jre-alpine COPY --from=builder /app/target/*-exec.jar app.jar ENTRYPOINT ["java", "-jar", "app.jar"] EXPOSE 8080
内容的提问来源于stack exchange,提问作者Prithivi Thiyagu
相关产品推荐
相关产品推荐

