Ошибка при запуске docker контейнера "NoClassDefFoundError" - PullRequest
1 голос
/ 01 мая 2020

Я пытаюсь докеризировать простое Spring Boot Application, созданное с помощью Maven.

Dockerfile:

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

Когда я запускаю .jar без контейнера (java -jar target/backend-1.0-SNAPSHOT.jar), все работает нормально и приложение работает.

Теперь я создаю контейнер с docker build -t company/backend .

Но когда я пытаюсь запустить контейнер docker с docker run -p 8080:8080 company/backend возникает следующая ошибка:

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

Кажется, что docker не находит основной класс, даже если он определен в моем пом. 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>

Основной класс:

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);
  }
}

1 Ответ

2 голосов
/ 02 мая 2020

В вашем пом. xml цель copy-dependencies указана на этапе install: слишком поздно пакет с банкой уже был сделан.

Я пытаюсь докеризировать простое Spring Boot Application, созданное с помощью Maven.

Вам не нужно указывать какой-либо плагин для создания толстой банки с весенней загрузкой. он может быть запущен контейнером docker.
Объявление этих плагинов подвержено ошибкам (и должно использоваться только в угловых случаях), в то время как цель repackage плагина maven с пружинной загрузкой прилагается по умолчанию на этапе пакета maven создаст для вас толстый jar:

Переупаковывает существующие архивы JAR и WAR, чтобы их можно было выполнить из командной строки с помощью java -jar

Juste удалите эти объявления плагинов и выполните mvn clean package, и это должно быть хорошо.

Примечание:

ОТ openjdk: последний

Не используйте latest в качестве версии изображения, а предпочитайте указанную c версию изображения, чтобы у вас могли быть неприятные сюрпризы. Поскольку вы используете JDK 8, вы можете указать JRE или JDK 8, например: FROM openjdk:8-jre-alpine.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...