java - 为什么在 docker 容器中执行命令与在 Dockerfile 中写入命令得到不同的结果?

标签 java docker maven dockerfile

Dockerfile:

FROM maven:latest

COPY . /usr/src/myapp

WORKDIR /usr/src/myapp

RUN mvn compile && mvn clean install

EXPOSE 8000/tcp

CMD ["mvn", "exec:java", "-Dexec.mainClass='com.demo.App'", "-e"]

执行docker run -it --rm <image>构建后,项目开始构建但失败:

[INFO] Error stacktraces are turned on.
[INFO] Scanning for projects...
Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-deploy-plugin/2.8.2/maven-deploy-plugin-2.8.2.pom
Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-deploy-plugin/2.8.2/maven-deploy-plugin-2.8.2.pom (7.1 kB at 12 kB/s)
...
WARNING]
java.lang.ClassNotFoundException: 'com.demo.App'
    at org.codehaus.mojo.exec.URLClassLoaderBuilder$ExecJavaClassLoader.loadClass (URLClassLoaderBuilder.java:198)
    at java.lang.ClassLoader.loadClass (ClassLoader.java:520)
    at org.codehaus.mojo.exec.ExecJavaMojo$1.run (ExecJavaMojo.java:271)
    at java.lang.Thread.run (Thread.java:833)
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  5.898 s
[INFO] Finished at: 2023-04-11T09:41:54Z
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.codehaus.mojo:exec-maven-plugin:3.1.0:java (default-cli) on project javasnippet: An exception occurred while executing the Java class. 'com.demo.App' -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.codehaus.mojo:exec-maven-plugin:3.1.0:java (default-cli) on project javasnippet: An exception occurred while executing the Java class. 'com.demo.App'
...
Caused by: java.lang.ClassNotFoundException: 'com.demo.App'
...

然后我注释掉CMD ["mvn", "exec:java", "-Dexec.mainClass='com.demo.App'", "-e"]在 Dockerfile 中,它给了我:

FROM maven:latest

COPY . /usr/src/myapp

WORKDIR /usr/src/myapp

RUN mvn compile && mvn clean install

EXPOSE 8000/tcp

# CMD ["mvn", "exec:java", "-Dexec.mainClass='com.demo.App'", "-e"]

再次构建并运行 docker run -it --rm <image> bash ,进入容器:

root@c9ed5282e511:/usr/src/myapp# ls
Dockerfile  pom.xml  src  target

然后我执行mvn exec:java -Dexec.mainClass='com.demo.App' -e启动项目,它可以工作:

root@c9ed5282e511:/usr/src/myapp# mvn exec:java -Dexec.mainClass='com.demo.App' -e
[INFO] Error stacktraces are turned on.
[INFO] Scanning for projects...
Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-deploy-plugin/2.8.2/maven-deploy-plugin-2.8.2.pom
...
Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/commons/commons-exec/1.3/commons-exec-1.3.jar (54 kB at 1.0 MB/s)
Server started at: Tue Apr 11 09:49:15 UTC 2023

请指导我为什么会发生这种情况以及我哪里做错了。

如果需要任何源代码,请告诉我。

最佳答案

您需要删除 JSON-array-syntax CMD 行内的单引号

CMD ["mvn", "exec:java", "-Dexec.mainClass=com.demo.App", "-e"]
#                                          ^          ^ no single quotes

当您通过 shell 运行此命令时,shell 解析器会看到单引号字符串,忽略其中任何标点符号的特殊含义,并删除单引号。在 Docker exec-form 命令中,不会发生任何处理; 唯一转义是使命令成为有效 JSON 数组所必需的。

这意味着在您的原始形式中,单引号已传递给实际命令。您会在最后一个异常中看到,Maven 尝试将字符串(仍然包含单引号)解释为 Java 类名。

关于java - 为什么在 docker 容器中执行命令与在 Dockerfile 中写入命令得到不同的结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75984568/

相关文章:

java - 在新游戏中清除我的 JFrame 和 JPanel

java - 从文件夹加载纹理

java - 在 Spring 中从 Controller 在 toastr 中显示消息

maven - 从命令行获取Gradle类路径

java - 安装第 3 方 jar

Java TimerTask 取消不起作用

docker - 在 Kubernetes Pod 上,ConfigMap 目录位置是什么?

azure - 在 Azure 中使用共享卷部署 docker 容器

docker - 我可以通过托管的 Traefik 容器为 Rancher Server 提供服务吗?

java - 从maven依赖中排除资源包(webjars)