докер с банкой мавена - PullRequest
0 голосов
/ 03 ноября 2019

Я запускаю проект maven в Docker-контейнере, получаю сообщение Не удалось найти или загрузить ошибку основного класса.

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

Вопрос: Как сделатьВы устанавливаете путь к файлу JAR в Docker?


Редактировать

Я тестировал следующую, но ту же проблему.

CMD ["java", "-cp", "Customer.jar:libs/*", "com.company.customers.Customer"]

Ошибка: не удалось найти или загрузить основной класс com.company.customers.Customer

1 Ответ

0 голосов
/ 03 ноября 2019

Это не проблема Docker, это проблема Java. Есть несколько способов определить записи classpath для запуска исполняемого jar.

Подход Shaded или Uber jar

В этом случае вы должны создать затененный jar, содержащий все зависимые классы в одном исполняемом jar-файле. ,Maven имеет плагин под названием Apache Maven Shade Plugin для создания этого артефакта uber-jar.

Наконец, просто запустите:

java -jar shaded-artifact.jar

или в Docker

CMD ["java", "-jar", "shaded-artifact.jar"]

Подход classpath командной строки

Если созданный артефакт jar требует наличия других (зависимых) jar, вы должны указать classpath. В этом случае скопируйте все необходимые jar-файлы в папку, например lib и используйте следующую команду:

java -cp '<name-of-jar.jar>:<path-of-dependencies>' <fully.quialified.main.ClassName>

Как видите, подстановочный знак (*) и несколько элементов classpath допускаются разделенными: *

java -cp 'Customer.jar:libs/*' com.mycompany.Customer

в Docker

CMD ["java", "-cp", "Customer.jar:libs/*", "com.mycompany.Customer"]

Classpath в подходе MANIFEST

После того, как вы собрали все эти зависимые артефакты в папку, вы просто добавляетеClass-Path введите в META-INF / MANIFEST.MF файл, подобный следующему:

Class-Path: . lib/*

и запустите

java -jar Customer.jar

илив Docker

CMD ["java", "-jar", "Customer.jar"]

Какая из них самая лучшая, зависит от многих вещей, которые вы должны выбрать.

Редактировать:

Судя по обновленному вопросу, кажется, что uber jar был создан плагином сборки с использованием предопределенного дескриптора jar-with-dependencies . Это создаст другой файл jar, который будет помещен в целевую (выходную) папку, и его имя оканчивается на -jar-with-dependencies.jar

  1. Используйте этот jar внутри основного артефакта.
  2. Выполните двойную проверку, чтобы убедиться, что все записи <mainClass> указывают на существующий класс. Вы упомянули три разных основных класса в одном и том же вопросе.
    • com.companyname.Customer

    • com.mycompany.Customer

    • com.company.customers.Customer

  3. Обратите внимание, что в Linux и Java учитывается регистр. Исходя из этого, имя класса должно быть точно Customer, а все имена папок должны быть строчными.

Надеюсь, это поможет.

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