#java #maven #maven-shade-plugin
#java #maven #maven-shade-плагин
Вопрос:
Я use maven-shade-plugin
в своем Java-проекте.
У меня есть вызываемый модуль core
, и я хотел бы упаковать все его зависимости в один jar. Я не хочу каждый раз создавать fat big jar и развертывать его вместе с кодом моего приложения. Размер моего приложения jar <1 МБ, но зависимости> 20 МБ
На моем сервере я бы запустил свое приложение следующим образом:
java -cp core.lib.jar:core.jar myApp
Мне нужно развертывать только core.jar
на моем сервере при изменении кода приложения и загружать core.lib.jar
только при изменении зависимостей (это очень редко).
Есть много документов о том, как создавать fat jar с исходными текстами Java, но я хочу исключить их и доставить на сервер независимо.
Для создания fat jar есть два плагина maven: assembly и shade. Я хочу придерживаться shade.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.3</version>
<executions>
<execution>
<phase>none</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<artifactSet>
<excludes>
<exclude>core</exclude>
</excludes>
</artifactSet>
</configuration>
</execution>
</executions>
</plugin>
Когда я запускаю mvn -pl core shade:shade
, я получаю сообщение об ошибке: core: Failed to create shaded artifact, project main artifact does not exist
Я думал, что этот вариант: core исключит мои источники из артефакта.
Я установил phase
none
значение, потому что я не хочу создавать fat jar, когда хочу запустить package
. Я хотел бы запустить mvn shade:shade
и обновить fat jar.
Я не эксперт в maven или его плагинах, поэтому любая помощь очень ценится 🙂
Комментарии:
1. Используя maven-assembly-plugin, вы можете упаковать jar / zip только с зависимостями и другой jar, содержащий код вашего приложения.
Ответ №1:
Я сам не использовал плагин shade, поэтому не могу дать никаких практических рекомендаций, однако, похоже, вам нужен многомодульный проект maven:
- Реорганизуйте свой проект (переместите папки), чтобы он выглядел следующим образом:
my-project
|__app
| |__src
| | |__main( (and all the production sources/resources inside)
| | |__test (all the tests/test resources inside)
| |__pom.xml
|__core-lib
| |__pom.xml
|__ pom.xml
my-project/pom.xml
может быть «многомодульным» агрегатором: он должен иметь <packaging>pom</packaging>
и иметь следующее:
<modules>
<module>app</module>
<module>core-lib</module>
</modules>
Теперь app
модуль может быть местом, где вы пишете код своего приложения. Он будет часто меняться, но не будет создавать fat jar — только обычный jar с скомпилированным кодом только из этого модуля (в вашем примере это будет артефакт размером 1 МБ).
core-lib
Модуль будет модулем, который в нем pom.xml
будет содержать определения плагина shade / assembly, и этот модуль будет отвечать за создание «fat jar». В своем dependences
разделе он перечислит все сторонние зависимости / код, которые вам придется менять «редко» (в вашем случае, с артефактом размером 20 МБ).
Если вам это нужно, модуль «app» может зависеть от модуля «core-lib», чтобы приложение имело доступ к классам из библиотеки.
Итак, ваш обычный рабочий процесс будет:
cd my-project/app
mvn package
Если вы хотите создавать как приложения, так и основные библиотеки, то:
cd my-project
mvn package
Комментарии:
1. Макет для всех видов проектов в Maven предназначен
src/main/java
для производственного кода.src/test/java
для тестового кода… следуйте соглашениям. Ваше предложение нарушает соглашение о парадигме конфигурации, чего следует избегать.2. @khmarbaise: Да, конечно, это была опечатка — я исправил ответ, спасибо, что указали на это. Сказав это, я хотел бы подчеркнуть (в основном для Александра, который задал этот вопрос), что основным «пунктом» ответа была рекомендация использовать многомодульную функцию maven.
3. Спасибо @MarkBramnik за предложение! Я уже использую многомодульную функцию maven. У меня уже есть такие модули, как: ядро, приложение, сервер и т.д. Я хотел бы избежать создания модулей только для целей упаковки и не создавать app-lib, server-lib, core-lib.
Ответ №2:
Мне нужно было переместить этот блок в плагин / конфигурацию
<artifactSet>
<excludes>
<exclude>core</exclude>
</excludes>
</artifactSet>
Раньше был в executions
блоке.
Теперь я могу запускать mvn -pl core shade:shade
и иметь fat jar только с зависимостями 🙂