Skip to content
Advertisement

Error when running docker container “NoClassDefFoundError”

I am trying to dockerize a simple Spring Boot Application, built with Maven.

Dockerfile:

FROM openjdk:latest
COPY target/backend-1.0-SNAPSHOT.jar app.jar
ENTRYPOINT ["java","-jar","app.jar"]

When I run the .jar without the container (java -jar target/backend-1.0-SNAPSHOT.jar), everything works fine and the app is running.

Now I create the container with docker build -t company/backend .

But when I try to run the docker container with docker run -p 8080:8080 company/backend the following error occurs:

Exception in thread "main" java.lang.NoClassDefFoundError: org/springframework/boot/SpringApplication
        at de.company.backend.Application.main(Application.java:10)
Caused by: java.lang.ClassNotFoundException: org.springframework.boot.SpringApplication
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:602)
        at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
        ... 1 more

It seems like docker does not find the main class, even though it is defined in my pom.xml:

<properties>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <mainClass>de.elbdev.backend.Application</mainClass>
</properties>

<build>
    <plugins>
        <plugin>
            <artifactId>maven-dependency-plugin</artifactId>
            <executions>
                <execution>
                    <phase>install</phase>
                    <goals>
                        <goal>copy-dependencies</goal>
                    </goals>
                    <configuration>
                        <outputDirectory>${project.build.directory}/lib</outputDirectory>
                    </configuration>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <artifactId>maven-jar-plugin</artifactId>
            <configuration>
                <archive>
                    <manifest>
                        <addClasspath>true</addClasspath>
                        <classpathPrefix>lib/</classpathPrefix>
                        <mainClass>${mainClass}</mainClass>
                    </manifest>
                </archive>
            </configuration>
        </plugin>
    </plugins>
</build>

Main Class:

package de.company.backend;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

  public static void main(String[] args) {
    SpringApplication.run(Application.class, args);
  }
}

Advertisement

Answer

In your pom.xml, the copy-dependencies goal is specified at the install phase : too late the package of the jar was already done.

I am trying to dockerize a simple Spring Boot Application, built with Maven.

You don’t need to declare any plugin to create a fat jar with spring boot that could be run by a docker container.
Declaring these plugins is error prone (and should be used only in corner cases) while the repackage goal of the spring boot maven plugin attached by default to the package phase of maven will create for you the fat jar :

Repackages existing JAR and WAR archives so that they can be executed from the command line using java -jar

Juste remove these plugins declarations and execute mvn clean package and it should be good.

Side note :

FROM openjdk:latest

Don’t use latest as image version but favor a specific version of the image othewhise you could have bad surprises. As you use JDK 8, you could specify a JRE or a JDK 8 such as : FROM openjdk:8-jre-alpine.

User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement