无法在Docker同一CMD中执行mvn exec并启动Tomcat的问题
解决Docker中执行mvn命令出现ClassNotFoundException的问题
错误原因
你使用的tomcat:10-jdk11镜像未预装Maven,报错中的org.codehaus.plexus.classworlds.launcher.Launcher是Maven运行时的核心依赖类,因此在该镜像中执行mvn命令必然找不到这个类。
解决方案
方案1:在Tomcat镜像中安装Maven
修改Dockerfile的第二阶段,添加Maven安装步骤,同时拷贝builder阶段的项目文件(mvn exec需要依赖项目的POM和编译产物):
FROM maven:3.8.5-openjdk-11-slim AS builder WORKDIR /app COPY . . RUN mvn clean package FROM tomcat:10-jdk11 # 安装Maven(基于Debian镜像,用apt安装) RUN apt-get update && apt-get install -y maven && rm -rf /var/lib/apt/lists/* WORKDIR /app # 拷贝builder阶段的整个项目目录,供mvn exec使用 COPY --from=builder /app /app COPY --from=builder /app/target/project.war /usr/local/tomcat/webapps/project.war EXPOSE 8080 # 注意:如果MyClass是前台运行,Tomcat不会启动,需将其后台运行 CMD nohup mvn exec:java -Dexec.cleanupDaemonThreads=false -Dexec.mainClass="MyClass" > /dev/null 2>&1 & && catalina.sh run
方案2:无需安装Maven,直接用Java命令运行主类(推荐)
在builder阶段提前拷贝项目依赖和编译后的类文件,在Tomcat镜像中直接用java命令启动主类,避免安装Maven带来的镜像体积膨胀:
FROM maven:3.8.5-openjdk-11-slim AS builder WORKDIR /app COPY . . RUN mvn clean package # 将项目依赖拷贝到单独目录 RUN mvn dependency:copy-dependencies -DoutputDirectory=/app/dependencies FROM tomcat:10-jdk11 WORKDIR /app # 拷贝编译后的类文件和依赖 COPY --from=builder /app/target/classes /app/classes COPY --from=builder /app/dependencies /app/dependencies COPY --from=builder /app/target/project.war /usr/local/tomcat/webapps/project.war EXPOSE 8080 # 后台运行主类,再启动Tomcat CMD nohup java -cp "classes:dependencies/*" MyClass > /dev/null 2>&1 & && catalina.sh run
额外注意事项
- 如果你的
MyClass需要持续运行(而非一次性执行),必须用后台运行方式(如nohup ... &),否则前一个命令会阻塞Tomcat启动。 - 若需要更可靠的多进程管理,可使用
supervisord工具配置两个进程的启动和监控,避免后台进程意外退出无法感知。
内容的提问来源于stack exchange,提问作者Aditya Karad
相关产品推荐
相关产品推荐

