Сборка fat jar в maven только с зависимостями

#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:

  1. Реорганизуйте свой проект (переместите папки), чтобы он выглядел следующим образом:
 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 только с зависимостями 🙂