带有Maven Jar的Docker [英] docker with maven jar
问题描述
我正在docker容器中运行一个Maven项目,我得到找不到或加载主类错误.
I'm running a maven project in a docker container, I'm getting Could not find or load main class error.
FROM maven:3.6.0-jdk-11-slim AS build
COPY src src
COPY pom.xml .
RUN mvn -f pom.xml clean package install
FROM openjdk:8-jre
COPY --from=build /target /opt/target
WORKDIR /target
RUN ls
CMD ["java", "-jar", "Customer.jar"]
上面的程序集是通过< build>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>com.companyname.Customer</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id> <!-- this is used for inheritance merges -->
<phase>package</phase> <!-- bind to the packaging phase -->
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
错误
错误:找不到或加载主类com.mycompany.Customer
Error: Could not find or load main class com.mycompany.Customer
问题:如何在docker中将类路径设置为jar文件?
Question: How do you set class path to a jar file in docker?
修改
我测试了以下但相同的问题.
I tested with the following but same issue.
CMD ["java", "-cp", "Customer.jar:libs/*", "com.company.customers.Customer"]
错误:找不到或加载主类com.company.customers.Customer
Error: Could not find or load main class com.company.customers.Customer
推荐答案
这不是Docker问题,而是Java问题.定义类路径条目以运行可执行jar的方法有多种.
It's not a Docker issue it's a Java issue. There are several ways to define classpath entries to run an executable jar.
在这种情况下,您需要创建一个带阴影的jar,该jar在一个可执行的jar文件中包含所有相关类.Maven有一个名为 Apache Maven Shade插件的插件来创建该插件uber-jar工件.
In this case you sould create a shaded jar which contains all dependent classes in one executable jar file. Maven has a plugin called Apache Maven Shade Plugin to create that uber-jar artifact.
最后运行:
java -jar shaded-artifact.jar
或在Docker
CMD ["java", "-jar", "shaded-artifact.jar"]
命令行类路径方法
如果创建的jar工件需要存在其他(从属)jar,则必须指定类路径.在这种情况下,将所有需要的罐子复制到一个文件夹中,例如 lib 并使用以下命令:
java -cp '<name-of-jar.jar>:<path-of-dependencies>' <fully.quialified.main.ClassName>
如您所见,通配符(*)和多个classpath元素都可以用分隔:
所以
As you can see either wildcard (*) character and multiple classpath element is allowed separated by :
so
java -cp 'Customer.jar:libs/*' com.mycompany.Customer
在Docker中
CMD ["java", "-cp", "Customer.jar:libs/*", "com.mycompany.Customer"]
MANIFEST方法中的类路径
在将所有这些从属工件收集到一个文件夹中之后,您只需在 META-INF/MANIFEST.MF 中添加一个 Class-Path
条目即可.strong>像这样的文件:
Classpath in MANIFEST approach
After you collecteded all those dependent artifact into a folder then you just add a Class-Path
entry into your META-INF/MANIFEST.MF file like this:
Class-Path: . lib/*
然后运行
java -jar Customer.jar
或在Docker
CMD ["java", "-jar", "Customer.jar"]
其中最好的取决于很多事情,您必须选择.
Which of those is the best depends on so many things, you have to choose.
基于更新后的问题,似乎uber jar由程序集插件使用 jar-with-dependencies 预定义描述符创建.这将创建另一个jar文件,该文件放置在目标(输出)文件夹下,其名称以 -jar-with-dependencies.jar
Based on updated question it seems the uber jar was created by assembly plugin using jar-with-dependencies predefined descriptor. This will create another jar file which placed under target (output) folder and its name ends with -jar-with-dependencies.jar
- 使用该罐子的基本人工制品.
- 仔细检查以确保所有
< mainClass>
条目都指向现有的类.您在同一问题中提到了三个不同的主类.
- Use that jar insead of basic artifact.
- Do a double check to make sure all of
<mainClass>
entries point to an existing class. You've mentioned three different main class in the same question.
com.companyname.Customer
com.companyname.Customer
com.mycompany.Customer
com.mycompany.Customer
com.company.customers.Customer
com.company.customers.Customer
希望有帮助.
这篇关于带有Maven Jar的Docker的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!