为什么在docker容器中执行命令与在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'
...

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

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数组语法CMD行中的单引号

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

当您通过shell运行此操作时,shell解析器会看到单引号字符串,忽略其中任何标点符号的特殊含义,并删除单引号。在Docker exec表单命令中,这些处理都不会发生;只有only转义才能使命令成为有效的JSON数组。

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

最新更新