java собрать Как создать исполняемый JAR с зависимостями с помощью Maven?




spring boot maven jar with dependencies (20)

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

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

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

https://code.i-harness.com

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

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


Вы можете добавить следующее к вашему pom.xml :

<build>
<defaultGoal>install</defaultGoal>
<plugins>
  <plugin>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>2.3.2</version>
    <configuration>
      <source>1.6</source>
      <target>1.6</target>
    </configuration>
  </plugin>
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>2.3.1</version>
    <configuration>
      <archive>
        <manifest>
          <addClasspath>true</addClasspath>
          <mainClass>com.mycompany.package.MainClass</mainClass>
        </manifest>
      </archive>
    </configuration>
  </plugin>
  <plugin>
    <artifactId>maven-assembly-plugin</artifactId>
    <configuration>
      <descriptorRefs>
        <descriptorRef>jar-with-dependencies</descriptorRef>
      </descriptorRefs>
      <archive>
        <manifest>
          <mainClass>com.mycompany.package.MainClass</mainClass>
        </manifest>
      </archive>
    </configuration>
    <executions>
      <execution>
        <id>make-my-jar-with-dependencies</id>
        <phase>package</phase>
        <goals>
          <goal>single</goal>
        </goals>
      </execution>
    </executions>
  </plugin>
</plugins>
</build>

Затем вам нужно переключиться через консоль в каталог, где находится pom.xml. Затем вам нужно выполнить сборку mvn: single, а затем ваш исполняемый JAR-файл с зависимостями, мы надеемся, будет построен. Вы можете проверить его при переключении на выходной (целевой) каталог с помощью cd ./target и запустить свою банку с помощью команды, аналогичной java -jar mavenproject1-1.0-SNAPSHOT-jar-with-dependencies.jar .

Я тестировал это с Apache Maven 3.0.3 .


Вы можете использовать плагин maven-shade для сборки uber jar, как показано ниже.

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>shade</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>

Вы можете использовать плагин зависимости, чтобы генерировать все зависимости в отдельном каталоге до фазы пакета, а затем включать это в путь к классам манифеста:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
        <execution>
            <id>copy-dependencies</id>
            <phase>prepare-package</phase>
            <goals>
                <goal>copy-dependencies</goal>
            </goals>
            <configuration>
                <outputDirectory>${project.build.directory}/lib</outputDirectory>
                <overWriteReleases>false</overWriteReleases>
                <overWriteSnapshots>false</overWriteSnapshots>
                <overWriteIfNewer>true</overWriteIfNewer>
            </configuration>
        </execution>
    </executions>
</plugin>
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <configuration>
        <archive>
            <manifest>
                <addClasspath>true</addClasspath>
                <classpathPrefix>lib/</classpathPrefix>
                <mainClass>theMainClass</mainClass>
            </manifest>
        </archive>
    </configuration>
</plugin>

В качестве альтернативы используйте ${project.build.directory}/classes/lib качестве OutputDirectory для интеграции всех jar-файлов в основную банку, но тогда вам нужно будет добавить пользовательский код загрузки классов для загрузки банок.


Вы также можете использовать этот плагин, это довольно хорошо, и я использую его для упаковки моих банок http://sonatype.github.io/jarjar-maven-plugin/


Длинный использовал плагин сборки maven , но я не смог найти решение проблемы с "already added, skipping" . Теперь я использую другой плагин - onejar-maven-plugin . Пример ниже ( mvn package build jar):

<plugin>
    <groupId>org.dstovall</groupId>
    <artifactId>onejar-maven-plugin</artifactId>
    <version>1.3.0</version>
    <executions>
        <execution>
            <configuration>
                <mainClass>com.company.MainClass</mainClass>
            </configuration>
            <goals>
                <goal>one-jar</goal>
            </goals>
        </execution>
    </executions>
</plugin>

Вам нужно добавить репозиторий для этого плагина:

<pluginRepositories>
    <pluginRepository>
        <id>onejar-maven-plugin.googlecode.com</id>
        <url>http://onejar-maven-plugin.googlecode.com/svn/mavenrepo</url>
    </pluginRepository>
</pluginRepositories>

Другой вариант, если вы действительно хотите переупаковать другое содержимое JAR внутри вашего единственного результирующего JAR, это плагин Maven Assembly . Он распаковывает и затем перегружает все в каталог через <unpack>true</unpack> . Тогда у вас будет второй проход, который встроил бы его в один массивный JAR.

onejar-maven-plugin . Это выполняет вышеупомянутые действия по переупаковке всего за один шаг.


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

сборка mvn: сборка


Используйте плагин maven-shade для упаковки всех зависимостей в один uber-jar. Его также можно использовать для создания исполняемого банку, указав основной класс. Попробовав использовать maven-assembly и maven-jar, я обнаружил, что этот плагин лучше всего подходит для моих потребностей.

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

См. Пример ниже

      <plugins>
    <!-- This plugin provides the capability to package the artifact in an uber-jar, including its dependencies and to shade - i.e. rename - the packages of some of the dependencies. -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <version>1.4</version>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>shade</goal>
                    </goals>
                    <configuration>
                        <artifactSet>
                        <!-- signed jars-->
                            <excludes>
                                <exclude>bouncycastle:bcprov-jdk15</exclude>
                            </excludes>
                        </artifactSet>

                         <transformers>
                            <transformer
                                implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                <!-- Main class -->
                                <mainClass>com.main.MyMainClass</mainClass>
                            </transformer>
                            <!-- Use resource transformers to prevent file overwrites -->
                            <transformer 
                                 implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                                <resource>properties.properties</resource>
                            </transformer>
                            <transformer
                                implementation="org.apache.maven.plugins.shade.resource.XmlAppendingTransformer">
                                <resource>applicationContext.xml</resource>
                            </transformer>
                            <transformer
                                implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                                <resource>META-INF/cxf/cxf.extension</resource>
                            </transformer>
                            <transformer
                                implementation="org.apache.maven.plugins.shade.resource.XmlAppendingTransformer">
                                <resource>META-INF/cxf/bus-extensions.xml</resource>
                            </transformer>
                     </transformers>
                    </configuration>
                </execution>
            </executions>
        </plugin>

    </plugins>

Плагин maven-assembly-plug отлично работал для меня. Я часами сидел с плагином maven-dependency и не мог заставить его работать. Основная причина заключалась в том, что я должен был явно определить в разделе конфигурации элементы артефакта, которые должны быть включены, как описано в documentation . Существует пример для случаев, когда вы хотите использовать его как: mvn dependency:copy , где не включены никакие объекты artifactItems, но это не работает.


Принимая ответ «Без ответа» и переформатируя его, мы имеем:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <configuration>
                <archive>
                    <manifest>
                        <addClasspath>true</addClasspath>
                        <mainClass>fully.qualified.MainClass</mainClass>
                    </manifest>
                </archive>
            </configuration>
        </plugin>
        <plugin>
            <artifactId>maven-assembly-plugin</artifactId>
            <configuration>
                <descriptorRefs>
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
            </configuration>
        </plugin>
    </plugins>
</build>

Затем я бы рекомендовал сделать это естественной частью вашей сборки, а не чем-то явно. Чтобы сделать это неотъемлемой частью вашей сборки, добавьте этот плагин в свой pom.xml и привяжите его к событию жизненного цикла package . Однако, вы понимаете, что вам нужно вызвать assembly:single цель, если вы поместите это в свой pom.xml, в то время как вы будете называть «сборка: сборка», если вы выполняете ее вручную из командной строки.

<project>
  [...]
  <build>
      <plugins>
          <plugin>
              <artifactId>maven-assembly-plugin</artifactId>
              <configuration>
                  <archive>
                      <manifest>
                          <addClasspath>true</addClasspath>
                          <mainClass>fully.qualified.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>
    [...]
  </build>
</project>

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

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

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

См. this для более подробной информации.

Класс: 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>

Чтобы решить эту проблему, мы будем использовать 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/


Это должно быть так:

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

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


Это также может быть вариант, вы сможете создать свой файл jar

<build>
    <plugins>
        <plugin>
            <!-- Build an executable JAR -->
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>2.4</version>
            <configuration>
                <archive>
                    <manifest>
                        <addClasspath>true</addClasspath>
                        <classpathPrefix>lib/</classpathPrefix>
                        <mainClass>WordListDriver</mainClass>
                    </manifest>
                </archive>
            </configuration>
        </plugin>
    </plugins>
</build>

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

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

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

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

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

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

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

java -jar ProjectMainJar.jar com..projectName.MainDynamicClassLoaderClass

Я попробовал самый опротестованный ответ здесь, и смог получить флягу. Но программа работает неправильно. Я не знаю, в чем причина. Когда я пытаюсь запустить из Eclipse , я получаю другой результат, но когда я запускаю jar из командной строки, я получаю другой результат (он выходит из строя с ошибкой времени выполнения программы).

У меня было такое же требование, как и у ОП, что у меня было слишком много (Maven) зависимостей для моего проекта. К счастью, единственным решением, которое сработало для меня, было то, что с помощью Eclipse . Очень просто и очень просто. Это не решение OP, а решение для тех, кто имеет аналогичное требование, но со многими зависимостями Maven,

1) Просто щелкните правой кнопкой мыши папку проекта (в Eclipse) и выберите « Export

2) Затем выберите Java -> Runnable Jar

3) Вам будет предложено выбрать расположение файла jar

4) Наконец, выберите класс, который имеет метод Main, который вы хотите запустить, и выберите « Package dependencies with the Jar file и нажмите « Finish


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

    <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


Добавить в pom.xml:

  <dependency>
            <groupId>com.jolira</groupId>
            <artifactId>onejar-maven-plugin</artifactId>
            <version>1.4.4</version>
  </dependency>

а также

<plugin>
       <groupId>com.jolira</groupId>
       <artifactId>onejar-maven-plugin</artifactId>
       <version>1.4.4</version>
       <executions>
              <execution>
                     <goals>
                         <goal>one-jar</goal>
                     </goals>
              </execution>
       </executions>
</plugin>

Это оно. Следующий пакет mvn также создаст еще одну жирную банку, включая все банки с зависимостями.


Уже есть миллионы ответов, я хотел бы добавить, что вам не нужно, <mainClass>если вам не нужно добавлять entryPoint в ваше приложение. Например, API могут не иметь mainметода.

Конфигурация плагина maven

  <build>
    <finalName>log-enrichment</finalName>
    <plugins>
      <plugin>
        <artifactId>maven-assembly-plugin</artifactId>
        <configuration>
          <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
          </descriptorRefs>
        </configuration>
      </plugin>
    </plugins>
  </build>

строить

mvn clean compile assembly:single

проверить

ll target/
total 35100
drwxrwx--- 1 root vboxsf     4096 Sep 29 16:25 ./
drwxrwx--- 1 root vboxsf     4096 Sep 29 16:25 ../
drwxrwx--- 1 root vboxsf        0 Sep 29 16:08 archive-tmp/
drwxrwx--- 1 root vboxsf        0 Sep 29 16:25 classes/
drwxrwx--- 1 root vboxsf        0 Sep 29 16:25 generated-sources/
drwxrwx--- 1 root vboxsf        0 Sep 29 16:25 generated-test-sources/
-rwxrwx--- 1 root vboxsf 35929841 Sep 29 16:10 log-enrichment-jar-with-dependencies.jar*
drwxrwx--- 1 root vboxsf        0 Sep 29 16:08 maven-status/




executable-jar