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

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

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


person soemirno    schedule 22.02.2009    source источник
comment
Пожалуйста, объясните, о какой цели плагина зависимостей вы говорите. Я не знаю цели, которая выполняет то, что запрашивает исходный вопрос: поместить все зависимости либо A) в банку авторов посредством переупаковки, либо B) создать исполняемую банку, у которой есть другие в пути к классам MANIFEST.MF   -  person Matthew McCullough    schedule 11.03.2009
comment
Вам может пригодиться этот rationaljava.com/2015 / 02 /   -  person Dan    schedule 02.02.2015
comment
comment
Обратитесь к stackoverflow.com/questions/35217128/   -  person Thanga    schedule 11.09.2017


Ответы (30)


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

и вы запускаете его с

mvn clean compile assembly:single

Цель компиляции должна быть добавлена ​​перед сборкой: одиночный или иначе код вашего собственного проекта не включается.

Подробности смотрите в комментариях.


Обычно эта цель привязана к фазе сборки и выполняется автоматически. Это гарантирует, что JAR будет собран при выполнении mvn install или выполнении развертывания / выпуска.

<plugin>
  <artifactId>maven-assembly-plugin</artifactId>
  <configuration>
    <archive>
      <manifest>
        <mainClass>fully.qualified.MainClass</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>
person Community    schedule 22.02.2009
comment
Спасибо @IAdapter. Обратите внимание, что вы всегда должны выполнять компиляцию перед рукой, потому что она просто помещает все, что есть в target / classes в JAR. Это гарантирует, что JAR будет включать все изменения, которые вы недавно внесли в исходный код. Итак, вы должны сделать что-то вроде: mvn clean compile assembly:single. - person Michael; 31.05.2011
comment
Я связал сборку: единственная цель с фазой пакета в моем проекте pom.xml, но она работает только тогда, когда я выполняю сборку mvn: single из командной строки. - person Sahil Dave; 23.10.2013
comment
Есть ли способ направить ‹mainClass› в класс в тестовом каталоге? У меня есть основной класс в org.core (структура каталогов существует в основном и тестовом), но maven включает только скомпилированные классы из основного, а не тестового. - person Prashant Vaidyanathan; 16.07.2014
comment
Можем ли мы использовать этот метод для java fx jar. Наша задача ant jar по умолчанию лучше. Но я сталкиваюсь с проблемами зависимостей с задачей ant jar. Посмотрите мой вопрос stackoverflow.com/questions/25915793/ - person Mubasher; 18.09.2014
comment
Я вижу, что это не добавляет банки в банку uber, вместо этого просто добавляет все файлы классов в банку. - person pitchblack408; 07.04.2015
comment
Совет: вы также можете добавить элемент <appendAssemblyId>false</appendAssemblyId> в configuration, чтобы избежать раздражающего суффикса -jar-with-dependencies в имени - person maxivis; 06.05.2015
comment
Плагин сборки maven может вызвать некоторые проблемы, потому что может переопределить некоторые зависимости, поэтому я не могу сказать вам использовать его! Вместо этого используйте плагин Maven Shade, который нам очень нравится. Мы потратили несколько дней, чтобы обнаружить, что плагин сборки maven отменяет некоторые зависимости, которые нарушают jar приложения. Посмотрите здесь: mkyong.com/ maven / create-a-fat-jar-file-maven-shade-plugin. - person user3774109; 09.03.2017
comment
8 уровней упаковки - безумие переборщить - person Niklas R.; 22.11.2017
comment
@maxivis Кажется, это работает, но выдает некоторые предупреждения. - person Raffi Khatchadourian; 02.02.2018
comment
что, если у меня нет основного метода или класса, мне просто нужен какой-то случайный java-файл для jar? - person parlad; 20.07.2018
comment
@parladneupane оставьте часть ‹archive› ... ‹/archive› - person gerardw; 24.10.2018
comment
Он не просил использовать плагины, maven должен сам компилировать с зависимостями без странных команд и плагинов. - person ; 21.11.2018
comment
@ user10201743 Просто чтобы дать небольшой контекст: Все в Maven - это плагин. Компилятор? maven-compiler-plugin. Тесты? maven-surefire-plugin. Эти два, включая сборку, являются официальными плагинами maven, поэтому их можно также рассматривать как часть maven (особенно потому, что, по крайней мере, сейчас, все три из них по умолчанию включены в ваш эффективный POM). - person Adowrath; 16.03.2019
comment
Я столкнулся с этим с помощью alexa-skills-kit-sdk-for-java, который работал хорошо до тех пор, пока не появились инструкции по созданию WAR-файла в Maven. В разделе «Развитие вашего первого навыка» говорится, что введите команду строки «mvn org.apache.maven.plugins: maven-assembly-plugin: 2.6: assembly -DdescriptorId = jar-with-dependencies package», которая не работает. Я поместил указанный выше плагин в «самый высокий POM» (ближайший к корневому файлу) и выполнил строковую команду «mvn clean compile assembly: single» из этого POM (каталога), и он работал отлично. - person Richard Bradley Smith; 25.05.2019
comment
Например, если ваш основной путь к классу src/main/java/com/example/ui/Main.java, вы должны написать так в pom.xml: <mainClass>com.example.ui.Main</mainClass>. - person Halil İbrahim Oymacı; 31.03.2020
comment
Спасибо, ребята, пригодилось - person Alejandro Gonzalez; 22.07.2020
comment
У меня возникли проблемы с этим, потому что я продолжал предпринимать различные попытки с использованием разных плагинов в разделе build pluginManagement plugins вместо плагинов сборки. Конечно, нет никаких сообщений об ошибке, чтобы сообщить вам об этой ошибке. - person Jack D Menendez; 06.12.2020
comment
И если вы здесь новичок, вы должны запустить эту новую скомпилированную программу, используя: java -jar target/*with-dependencies.jar, и вы можете добавить любые аргументы командной строки, которые хотите передать своей программе. - person William Entriken; 19.02.2021
comment
это НЕ исполняемый файл - person Enerccio; 28.06.2021

Вы можете использовать dependency-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-файлов в основную jar, но тогда вам нужно будет добавить собственный код загрузки классов для загрузки jar-файлов.

person André Aronsen    schedule 01.12.2010

См. исполняемый-jar-with-maven-example (GitHub)

Примечания

Эти плюсы и минусы предоставлены Стефаном.


Для ручного развертывания

  • Плюсы
  • Cons
    • Dependencies are out of the final jar.

Копировать зависимости в определенный каталог

<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}/${project.build.finalName}.lib</outputDirectory>
      </configuration>
    </execution>
  </executions>
</plugin>

Сделайте исполняемый файл Jar и путь к классам осведомленным

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-jar-plugin</artifactId>
  <configuration>
    <archive>
      <manifest>
        <addClasspath>true</addClasspath>
        <classpathPrefix>${project.build.finalName}.lib/</classpathPrefix>
        <mainClass>${fully.qualified.main.class}</mainClass>
      </manifest>
    </archive>
  </configuration>
</plugin>

На этом этапе jar фактически исполняется с элементами внешнего пути к классам.

$ java -jar target/${project.build.finalName}.jar

Сделать развертываемые архивы

Файл jar может исполняться только в том же каталоге ...lib/. Нам нужно сделать архивы для развертывания с каталогом и его содержимым.

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-antrun-plugin</artifactId>
  <executions>
    <execution>
      <id>antrun-archive</id>
      <phase>package</phase>
      <goals>
        <goal>run</goal>
      </goals>
      <configuration>
        <target>
          <property name="final.name" value="${project.build.directory}/${project.build.finalName}"/>
          <property name="archive.includes" value="${project.build.finalName}.${project.packaging} ${project.build.finalName}.lib/*"/>
          <property name="tar.destfile" value="${final.name}.tar"/>
          <zip basedir="${project.build.directory}" destfile="${final.name}.zip" includes="${archive.includes}" />
          <tar basedir="${project.build.directory}" destfile="${tar.destfile}" includes="${archive.includes}" />
          <gzip src="${tar.destfile}" destfile="${tar.destfile}.gz" />
          <bzip2 src="${tar.destfile}" destfile="${tar.destfile}.bz2" />
        </target>
      </configuration>
    </execution>
  </executions>
</plugin>

Теперь у вас есть target/${project.build.finalName}.(zip|tar|tar.bz2|tar.gz), каждый из которых содержит jar и lib/*.


Плагин сборки Apache Maven

  • Плюсы
  • Cons
    • No class relocation support (use maven-shade-plugin if class relocation is needed).
<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-assembly-plugin</artifactId>
  <executions>
    <execution>
      <phase>package</phase>
      <goals>
        <goal>single</goal>
      </goals>
      <configuration>
        <archive>
          <manifest>
            <mainClass>${fully.qualified.main.class}</mainClass>
          </manifest>
        </archive>
        <descriptorRefs>
          <descriptorRef>jar-with-dependencies</descriptorRef>
        </descriptorRefs>
      </configuration>
    </execution>
  </executions>
</plugin>

У вас есть target/${project.bulid.finalName}-jar-with-dependencies.jar.


Плагин Apache Maven Shade

  • Плюсы
  • Минусы
<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-shade-plugin</artifactId>
  <executions>
    <execution>
      <goals>
        <goal>shade</goal>
      </goals>
      <configuration>
        <shadedArtifactAttached>true</shadedArtifactAttached>
        <transformers>
          <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
            <mainClass>${fully.qualified.main.class}</mainClass>
          </transformer>
        </transformers>
      </configuration>
    </execution>
  </executions>
</plugin>

У вас target/${project.build.finalName}-shaded.jar.


onejar-maven-plugin

  • Плюсы
  • Cons
    • Not actively supported since 2012.
<plugin>
  <!--groupId>org.dstovall</groupId--> <!-- not available on the central -->
  <groupId>com.jolira</groupId>
  <artifactId>onejar-maven-plugin</artifactId>
  <executions>
    <execution>
      <configuration>
        <mainClass>${fully.qualified.main.class}</mainClass>
        <attachToBuild>true</attachToBuild>
        <!-- https://code.google.com/p/onejar-maven-plugin/issues/detail?id=8 -->
        <!--classifier>onejar</classifier-->
        <filename>${project.build.finalName}-onejar.${project.packaging}</filename>
      </configuration>
      <goals>
        <goal>one-jar</goal>
      </goals>
    </execution>
  </executions>
</plugin>

Плагин Spring Boot Maven

  • Плюсы
  • Cons
    • Add potential unecessary Spring and Spring Boot related classes.
<plugin>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-maven-plugin</artifactId>
  <executions>
    <execution>
      <goals>
        <goal>repackage</goal>
      </goals>
      <configuration>
        <classifier>spring-boot</classifier>
        <mainClass>${fully.qualified.main.class}</mainClass>
      </configuration>
    </execution>
  </executions>
</plugin>

У вас есть target/${project.bulid.finalName}-spring-boot.jar.

person Jin Kwon    schedule 02.06.2014

Взяв ответ без ответа и переформатировав его, мы получим:

<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, в то время как вы должны вызвать 'assembly: assembly', если выполняете его вручную из командной строки.

<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>
person Matthew McCullough    schedule 26.02.2009

Используйте maven-shade-plugin, чтобы упаковать все зависимости в один uber-jar. Его также можно использовать для создания исполняемого файла 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>
person Vijay Katam    schedule 22.09.2010

Вы можете использовать плагин 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>
person Minisha    schedule 26.10.2017

Давно использовал плагин сборки maven, но мне не удалось найти решение проблемы с _ 1_. Теперь я использую другой плагин - onejar-maven-plugin . Пример ниже (mvn package сборка 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>
person marioosh    schedule 13.03.2012

Вы можете использовать maven-dependency-plugin, но вопрос был в том, как создать исполняемый JAR. Для этого требуется следующее изменение ответа Мэтью Франглена (кстати, использование плагина зависимостей требует больше времени для создания при запуске с чистой цели):

<build>
    <plugins>
        <plugin>
            <artifactId>maven-jar-plugin</artifactId>
            <configuration>
                <archive>
                    <manifest>
                        <mainClass>fully.qualified.MainClass</mainClass>
                    </manifest>
                </archive>
            </configuration>
        </plugin>
        <plugin>
            <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>
        </resource>
    </resources>
</build>
person Community    schedule 13.10.2009

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

Другой вариант - плагин OneJar. Это выполнит указанные выше действия по переупаковке за один шаг.

person Matthew McCullough    schedule 11.03.2009

Вы можете добавить в свой 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 assembly: single, и тогда ваш исполняемый файл JAR с зависимостями, надеюсь, будет построен. Вы можете проверить это, переключившись в выходной (целевой) каталог с помощью cd ./target и запустив jar-файл с помощью команды, похожей на java -jar mavenproject1-1.0-SNAPSHOT-jar-with- dependencies.jar.

Я тестировал это с помощью Apache Maven 3.0.3.

person Benny Neugebauer    schedule 13.08.2011

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

    <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

person dsutherland    schedule 23.11.2015

Вы можете комбинировать 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
person Oliver    schedule 26.11.2011
comment
Плагин Shade теперь имеет средства указания записи Main-Class в манифесте: maven.apache.org/plugins/maven-shade-plugin/examples/ - person Chadwick; 28.02.2012

На мой взгляд, Кен Лю прав. Плагин зависимостей 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>
person Matthew Franglen    schedule 09.09.2009

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

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

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

person kac-ani    schedule 05.03.2010
comment
Получение этой проблемы: org.apache.maven.lifecycle.LifecycleExecutionException: не удалось выполнить цель org.apache.maven.plugins: maven-dependency-plugin: 3.1.2: unpack-dependencies (unpack-dependencies) в службах проекта: неизвестный архиватор тип - person MoHaN K RaJ; 15.12.2020

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

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

Ни один из них не делает того, что вам нужно: ищите файл в пути к классам. Конечно, вам нужно добавить пакет, в котором общая сборка находится в пути к классам maven-assembly-plugin (см. Ниже). Если вы используете Maven 2.x (не 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>
person Rostislav Stříbrný    schedule 13.03.2011

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

person Anoop Rai    schedule 01.09.2016

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

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

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

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

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

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

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

java -jar ProjectMainJar.jar com.stackoverflow.projectName.MainDynamicClassLoaderClass
person SRG    schedule 28.12.2009

Чтобы создать исполняемый файл JAR из самой командной строки, просто запустите следующую команду из пути к проекту:

mvn assembly:assembly
person Mayank    schedule 14.09.2010
comment
Я думаю, вам еще нужно кое-что сделать в pom.xml, иначе вы получите Error reading assemblies: No assembly descriptors found.. В любом случае это то, что происходит со мной. - person Sridhar Sarnobat; 08.09.2017

Что-то, что сработало для меня, было:

  <plugin>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
      <execution>
        <id>unpack-dependencies</id>
        <phase>prepare-package</phase>
        <goals>
          <goal>unpack-dependencies</goal>
        </goals>
        <configuration>
          <outputDirectory>${project.build.directory}/classes</outputDirectory>
        </configuration>
      </execution>

    </executions>
  </plugin>


  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <executions>
      <execution>
        <id>unpack-dependencies</id>
        <phase>package</phase>
      </execution>
    </executions>
    <configuration>
      <archive>
        <manifest>
          <addClasspath>true</addClasspath>
          <classpathPrefix>lib/</classpathPrefix>
          <mainClass>SimpleKeyLogger</mainClass>
        </manifest>
      </archive>
    </configuration>
  </plugin>

У меня был необычный случай, потому что моя зависимость была системной:

<dependency>
  ..
  <scope>system</scope>
  <systemPath>${project.basedir}/lib/myjar.jar</systemPath>
</dependency>

Я изменил код, предоставленный @ user189057, с изменениями: 1) maven-dependency-plugin выполняется на этапе "prepare-package" 2) Я извлекаю распакованные классы непосредственно в "target / classes"

person fascynacja    schedule 24.09.2013

Это лучший способ, который я нашел:

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>2.4</version>
    <configuration>
      <archive>
        <manifest>
        <addClasspath>true</addClasspath>
        <mainClass>com.myDomain.etc.MainClassName</mainClass>
        <classpathPrefix>dependency-jars/</classpathPrefix>
        </manifest>
      </archive>
    </configuration>
  </plugin>
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <version>2.5.1</version>
    <executions>
      <execution>
        <id>copy-dependencies</id>
        <phase>package</phase>
        <goals>
            <goal>copy-dependencies</goal>
        </goals>
        <configuration>
            <outputDirectory>
               ${project.build.directory}/dependency-jars/
            </outputDirectory>
        </configuration>
      </execution>
    </executions>
  </plugin>

В этой конфигурации все зависимости будут расположены в /dependency-jars. В моем приложении нет класса Main, только контекстные, но у одной из моих зависимостей есть класс Main (com.myDomain.etc.MainClassName), который запускает сервер JMX и получает параметр start или stop. Итак, с этим я смог запустить свое приложение следующим образом:

java -jar ./lib/TestApp-1.0-SNAPSHOT.jar start

Я жду, это будет полезно для всех вас.

person EliuX    schedule 09.03.2015

Я сравнил плагины дерева, упомянутые в этом посте. Я создал 2 баночки и каталог со всеми банками. Я сравнил результаты и определенно лучший плагин maven-shade. Моя проблема заключалась в том, что у меня есть несколько ресурсов Spring, которые необходимо объединить, а также службы jax-rs и JDBC. Все они были правильно объединены плагином тени по сравнению с плагином maven-assembly-plugin. В этом случае пружина не сработает, если вы не скопируете их в свою папку ресурсов и не объедините вручную один раз. Оба плагина выводят правильное дерево зависимостей. У меня было несколько областей, таких как тест, предоставление, компиляция и т. Д., Тест и предоставленные были пропущены обоими плагинами. Они оба создали один и тот же манифест, но я смог объединить лицензии с плагином оттенка, используя их преобразователь. С плагином maven-dependency-plugin, конечно, у вас нет этих проблем, потому что банки не извлекаются. Но, как указали некоторые другие, для правильной работы вам необходимо иметь с собой один дополнительный файл (ы). Вот фрагмент файла pom.xml

            <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>
                        <includeScope>compile</includeScope>
                        <excludeTransitive>true</excludeTransitive>
                        <overWriteReleases>false</overWriteReleases>
                        <overWriteSnapshots>false</overWriteSnapshots>
                        <overWriteIfNewer>true</overWriteIfNewer>
                    </configuration>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>2.6</version>
            <configuration>
                <archive>
                    <manifest>
                        <addClasspath>true</addClasspath>
                        <mainClass>com.rbccm.itf.cdd.poller.landingzone.LandingZonePoller</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>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <version>2.4.3</version>
            <configuration>
                <shadedArtifactAttached>false</shadedArtifactAttached>
                <keepDependenciesWithProvidedScope>false</keepDependenciesWithProvidedScope>
                <transformers>
                    <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                        <resource>META-INF/services/javax.ws.rs.ext.Providers</resource>
                    </transformer>
                    <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                        <resource>META-INF/spring.factories</resource>
                    </transformer>
                    <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                        <resource>META-INF/spring.handlers</resource>
                    </transformer>
                    <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                        <resource>META-INF/spring.schemas</resource>
                    </transformer>
                    <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                        <resource>META-INF/spring.tooling</resource>
                    </transformer>
                    <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
                    <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"/>
                    <transformer implementation="org.apache.maven.plugins.shade.resource.ApacheLicenseResourceTransformer">
                    </transformer>
                </transformers>
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>shade</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
person Fabio    schedule 24.02.2016

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

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

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

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

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

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

person Rocky Inde    schedule 10.10.2014

Это также может быть вариант, вы сможете создать свой файл 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>
person salmanbw    schedule 25.11.2015

Для тех, кто ищет варианты исключения определенных зависимостей из uber-jar, это решение, которое сработало для меня:

<project...>
<dependencies>
        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-core_2.11</artifactId>
            <version>1.6.1</version>
            <scope>provided</scope> <=============
        </dependency>
</dependencies>
<build>
        <plugins>
            <plugin>
                <artifactId>maven-assembly-plugin</artifactId>
                <configuration>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                    <archive>
                        <manifest>
                            <mainClass>...</mainClass>
                        </manifest>
                    </archive>
                </configuration>
                <executions>
                    <execution>
                        <id>make-assembly</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

Так что это не конфигурация плагина mvn-assembly-plugin, а свойство зависимости.

person Paul Bormans    schedule 03.05.2016

Уже есть миллионы ответов, я хотел добавить, что вам не нужно <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/
person prayagupd    schedule 29.09.2016

Добавьте в 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 также дополнительно создаст одну толстую банку, включая все банки зависимостей.

person Aydin K.    schedule 21.06.2017

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

person Chris    schedule 24.05.2013

В этом сообщении блога показан другой подход с объединением плагинов maven-jar и maven-assembly. С конфигурацией сборки xml из сообщения в блоге также можно контролировать, будут ли зависимости расширяться или просто собираться в папку и ссылаться на запись пути к классам в манифесте:

Идеальное решение - включить jar-файлы в папку lib, а файл manifest.mf основного jar-файла включает все jar-файлы в пути к классам.

И именно он описан здесь: https://caffebig.wordpress.com/2013/04/05/executable-jar-file-with-dependent-jars-using-maven/

person Jan Ziegler    schedule 27.05.2015

Я надеюсь, что мой опыт может кому-то помочь: я хочу перенести свое приложение Spring (используя клиент cas) на Spring Boot (1.5, а не 2.4). Я столкнулся со многими проблемами, такими как:

нет основного атрибута манифеста в target / cas-client-web.jar

Я хочу сделать одну уникальную банку со всеми зависимостями. После нескольких дней поисков в Интернете. Я могу выполнить свою работу с помощью этих строк:

         <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <fork>true</fork>
                <mainClass>${start-class}</mainClass>
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>repackage</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <artifactId>maven-assembly-plugin</artifactId>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <archive>
                    <manifest>
                        <addClasspath>true</addClasspath>
                        <mainClass>${start-class}</mainClass>
                    </manifest>
                </archive>
                <descriptorRefs>
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
            </configuration>
        </plugin>

with start-class - ваш основной класс

<properties>
    <java.version>1.8</java.version>
    <start-class>com.test.Application</start-class>
</properties>

И мое приложение выглядит так:

package com.test;

import java.util.Arrays;

import com.test.TestProperties;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;


@SpringBootApplication
@EnableAutoConfiguration
@EnableConfigurationProperties({TestProperties.class})
public class Application {

public static void main(String[] args) {
    SpringApplication.run(Application.class, args);
}

@Bean
public CommandLineRunner commandLineRunner(ApplicationContext ctx) {
    return args -> {

        System.out.println("Let's inspect the beans provided by Spring Boot:");

        String[] beanNames = ctx.getBeanDefinitionNames();
        Arrays.sort(beanNames);
        for (String beanName : beanNames) {
            System.out.println(beanName);
        }

    };
}

}
person uwevil    schedule 25.06.2020

Хорошо, это мое решение. Я знаю, что он не использует файл pom.xml. Но у меня возникла проблема с компиляцией и запуском моей программы на Netbeans, но она не удалась, когда я попробовал Java -jar MyJarFile.jar. Теперь я не совсем понимаю Maven, и я думаю, что именно поэтому возникли проблемы с тем, чтобы Netbeans 8.0.2 включил мой файл jar в библиотеку, чтобы поместить их в файл jar. Я думал о том, как использовал файлы jar без Maven в Eclipse.

Это Maven, который может компилировать все зависимости и плагины. Не Netbeans. (Если вы можете получить Netbeans и использовать для этого java .jar, расскажите мне, как (^. ^) V)

[Решено - для Linux], открыв терминал.

потом

cd /MyRootDirectoryForMyProject

Следующий

mvn org.apache.maven.plugins:maven-compiler-plugin:compile

Следующий

mvn install

Это создаст файл jar в целевом каталоге.

MyJarFile-1.0-jar-with-dependencies.jar

Теперь

cd target

(Вам может потребоваться запустить: chmod +x MyJarFile-1.0-jar-with-dependencies.jar)

И наконец

java -jar MyJarFile-1.0-jar-with-dependencies.jar

Пожалуйста, посмотри

https://cwiki.apache.org/confluence/display/MAVEN/LifecyclePhaseNotFoundException

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

person mycowan    schedule 13.02.2015
comment
Попробуйте открыть проект Maven, созданный с помощью Netbeans. Основное правило Netbeans - всегда создавать проект Maven, а не «приложение Java». Добавьте плагин maven-shade, как один из ответов. Работает как шарм. - person rjdkolb; 02.11.2015