Как я могу создать исполняемый JAR с зависимостями, используя Maven? - PullRequest
2171 голосов
/ 22 февраля 2009

Я хочу упаковать свой проект в один исполняемый файл JAR для распространения.

Как сделать так, чтобы проект Maven упаковывал все JAR-файлы зависимостей в мой выходной JAR-файл?

Ответы [ 34 ]

11 голосов
/ 26 ноября 2011

Вы можете объединить maven-shade-plugin и maven-jar-plugin.

  • maven-shade-plugin упаковывает ваши классы и все зависимости в один файл jar.
  • Сконфигурируйте maven-jar-plugin, чтобы указать основной класс исполняемого файла jar (см. Настройка пути к классам , глава «Создание исполняемого файла Jar»).

Пример конфигурации POM для maven-jar-plugin:

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>2.3.2</version>
            <configuration>
                <archive>
                    <manifest>
                        <addClasspath>true</addClasspath>
                        <mainClass>com.example.MyMainClass</mainClass>
                    </manifest>
                </archive>
            </configuration>
        </plugin>

Наконец, создайте исполняемый файл jar, вызвав:

mvn clean package shade:shade
11 голосов
/ 23 ноября 2015

Я прошел через все эти ответы, пытаясь создать полный исполняемый файл jar, содержащий все зависимости, и ни один из них не работал правильно. Ответ - плагин Shade, он очень прост и понятен.

    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-shade-plugin</artifactId>
      <version>2.3</version>
      <executions>
         <!-- Run shade goal on package phase -->
        <execution>
        <phase>package</phase>
        <goals>
            <goal>shade</goal>
        </goals>
        <configuration>
          <transformers>
             <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                <mainClass>path.to.MainClass</mainClass>
             </transformer>
          </transformers>
        </configuration>
          </execution>
      </executions>
    </plugin>

Помните, что для правильной работы ваших зависимостей должна быть область компиляции или времени выполнения.

Этот пример взят с mkyong.com

9 голосов
/ 14 октября 2016

Вот исполняемый плагин jar для Maven, который мы используем в Credit Karma. Создает банку банок с загрузчиком классов, способную загружать классы из вложенных банок. Это позволяет вам иметь один и тот же classpath в dev и prod и при этом хранить все классы в одном подписанном jar-файле.

https://github.com/creditkarma/maven-exec-jar-plugin

А вот сообщение в блоге с подробной информацией о плагине и почему мы его сделали: https://engineering.creditkarma.com/general-engineering/new-executable-jar-plugin-available-apache-maven/

9 голосов
/ 09 сентября 2009

Кен Лю, по моему мнению, прав. Плагин зависимостей maven позволяет расширять все зависимости, которые затем можно рассматривать как ресурсы. Это позволяет вам включать их в основной артефакт. Использование плагина сборки создает вторичный артефакт, который может быть трудно изменить - в моем случае я хотел добавить пользовательские записи манифеста. Мой помет закончился как:

<project>
 ...
 <build>
  <plugins>
   <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
     <execution>
      <id>unpack-dependencies</id>
      <phase>package</phase>
      <goals>
       <goal>unpack-dependencies</goal>
      </goals>
     </execution>
    </executions>
   </plugin>
  </plugins>
  ...
  <resources>
   <resource>
    <directory>${basedir}/target/dependency</directory>
    <targetPath>/</targetPath>
   </resource>
  </resources>
 </build>
 ...
</project>
8 голосов
/ 05 марта 2010

Должно быть так:

    <plugin>
                <artifactId>maven-dependency-plugin</artifactId>
                <executions>
                        <execution>
                                <id>unpack-dependencies</id>
                                <phase>generate-resources</phase>
                                <goals>
                                        <goal>unpack-dependencies</goal>
                                </goals>
                        </execution>
                </executions>
        </plugin>

Распаковка должна быть в фазе создания ресурсов, потому что, если в фазе упаковки, она не будет включена в качестве ресурсов. Попробуйте чистую упаковку, и вы увидите.

7 голосов
/ 11 февраля 2011

Используйте плагин onejar , чтобы собрать его как один исполняемый файл jar, в который упакованы все файлы jar зависимостей. Это решило мою проблему, которая была похожа на эту. Когда использовался плагин сборки, он распаковывал все jar-файлы зависимостей в исходную папку и перепаковывал их как jar-файл, переписывал все похожие реализации, которые были в моем коде, которые имели одинаковые имена классов. onejar - это простое решение.

7 голосов
/ 13 марта 2011

Проблема с поиском общего файла сборки с помощью maven-assembly-plugin-2.2.1?

Попробуйте использовать параметр конфигурации descriptorId вместо параметров descriptors / descriptor или descriptorRefs / descriptorRef.

Никто из них не делает то, что вам нужно: ищите файл в classpath. Конечно, вам нужно добавить пакет, в котором общая сборка находится в пути к классу maven-assembly-plugin (см. Ниже). Если вы используете Maven 2.x (не Maven 3.x), вам может понадобиться добавить эту зависимость в самый верхний родительский pom.xml в разделе pluginManagement.

Подробнее см. .

Класс: org.apache.maven.plugin.assembly.io.DefaultAssemblyReader

Пример:

        <!-- Use the assembly plugin to create a zip file of all our dependencies. -->
        <plugin>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>2.2.1</version>
            <executions>
                <execution>
                    <id>make-assembly</id>
                    <phase>package</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                    <configuration>
                        <descriptorId>assembly-zip-for-wid</descriptorId>
                    </configuration>
                </execution>
            </executions>
            <dependencies>
                <dependency>
                    <groupId>cz.ness.ct.ip.assemblies</groupId>
                    <artifactId>TEST_SharedAssemblyDescriptor</artifactId>
                    <version>1.0.0-SNAPSHOT</version>
                </dependency>
            </dependencies>
        </plugin>
5 голосов
/ 28 декабря 2009

Я не буду отвечать прямо на вопрос, так как другие уже делали это раньше, но мне действительно интересно, стоит ли встраивать все зависимости в сам файл проекта.

Я вижу смысл (простота развертывания / использования), но это зависит от варианта использования вашего объекта (и могут быть альтернативы (см. Ниже)).

Если вы используете его полностью автономно, почему бы и нет.

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

Хорошая альтернатива:

  • разверните ваше приложение как .zip / .war: архив содержит jar вашего проекта и все зависимые jar;
  • использовать механизм динамического загрузчика классов (см. Spring, или вы можете легко сделать это самостоятельно), чтобы иметь единственную точку входа в ваш проект (один класс для запуска - см. Механизм манифеста в другом ответе), который добавит (динамически ) к текущему classpath все остальные необходимые банки.

Подобным образом, имея в конце всего лишь манифест и «специальный динамический основной загрузчик классов», вы можете начать свой проект с:

java -jar ProjectMainJar.jar com.stackoverflow.projectName.MainDynamicClassLoaderClass
4 голосов
/ 01 сентября 2016

Для решения этой проблемы мы будем использовать Maven Assembly Plugin, который создаст JAR вместе с зависимыми JAR-файлами в один исполняемый JAR-файл. Просто добавьте ниже конфигурацию плагина в ваш файл pom.xml.

<build>
   <pluginManagement>
      <plugins>
         <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-assembly-plugin</artifactId>
            <configuration>
               <archive>
                  <manifest>
                     <addClasspath>true</addClasspath>
                     <mainClass>com.your.package.MainClass</mainClass>
                  </manifest>
               </archive>
               <descriptorRefs>
                  <descriptorRef>jar-with-dependencies</descriptorRef>
               </descriptorRefs>
            </configuration>
            <executions>
               <execution>
                  <id>make-my-jar-with-dependencies</id>
                  <phase>package</phase>
                  <goals>
                     <goal>single</goal>
                  </goals>
               </execution>
            </executions>
         </plugin>
      </plugins>
   </pluginManagement>
</build>

После этого не забудьте запустить инструмент MAVEN с этой командой mvn clean compile Assembly: single

http://jkoder.com/maven-creating-a-jar-together-with-its-dependency-jars-into-a-single-executable-jar-file/

3 голосов
/ 14 сентября 2010

Если вы хотите, если из самой командной строки. Просто запустите приведенную ниже команду из пути проекта

мвн сборка: сборка

...