Reputation: 2200
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"]
above assembly was created with following plugin in <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>
Error
Error: Could not find or load main class com.mycompany.Customer
Question: How do you set class path to a jar file in docker?
Edit
I tested with the following but same issue.
CMD ["java", "-cp", "Customer.jar:libs/*", "com.company.customers.Customer"]
Error: Could not find or load main class com.company.customers.Customer
Upvotes: 1
Views: 5161
Reputation: 3263
It's not a Docker issue it's a Java issue. There are several ways to define classpath entries to run an executable 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.
Finally just run:
java -jar shaded-artifact.jar
or in Docker
CMD ["java", "-jar", "shaded-artifact.jar"]
If the created jar artifact requires the existence of other (dependent) jars you have to specify the classpath. In this case copy all required jars into a folder e.g. lib and use the following command:
java -cp '<name-of-jar.jar>:<path-of-dependencies>' <fully.quialified.main.ClassName>
As you can see either wildcard (*) character and multiple classpath element is allowed separated by :
so
java -cp 'Customer.jar:libs/*' com.mycompany.Customer
in Docker
CMD ["java", "-cp", "Customer.jar:libs/*", "com.mycompany.Customer"]
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/*
and run
java -jar Customer.jar
or in Docker
CMD ["java", "-jar", "Customer.jar"]
Which of those is the best depends on so many things, you have to choose.
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>
entries point to an existing class. You've mentioned three different main class in the same question.
com.companyname.Customer
com.mycompany.Customer
com.company.customers.Customer
Customer
exactly and all folder names must be lowercase.Hope it helps.
Upvotes: 3