29

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

17

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

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

5 ответ(ов)

28

Чтобы правильно настроить Maven для сборки вашего проекта с использованием плагина maven-assembly-plugin, вам нужно добавить соответствующие конфигурации в ваш файл pom.xml. Вот пример настройки, который включает в себя необходимые секции:

<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>
      <executions>
        <execution>
          <id>make-assembly</id> <!-- это используется для объединения наследования -->
          <phase>package</phase> <!-- привязка к фазе упаковки -->
          <goals>
            <goal>single</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>

Как видно из приведенного выше кода, плагин maven-assembly-plugin настраивается так, чтобы собирать исполняемый JAR, включающий все зависимости вашего проекта. Важно отметить, что цель compile должна быть выполнена перед выполнением assembly:single, иначе код вашего проекта не будет включен в сборку.

Для выполнения сборки запустите следующую команду:

mvn clean compile assembly:single

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

Если вы добавите вышеописанные параметры в ваш pom.xml, вы гарантируете, что ваш JAR файл будет собираться правильно при соответствующих командах Maven.

4

Вы можете использовать плагин maven-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-файлов.

1

Чтобы упаковать все зависимости в один uber-JAR файл, используйте плагин maven-shade-plugin. Он также может быть использован для создания исполняемого JAR файла, указав основный класс. После попыток использовать maven-assembly и maven-jar, я пришёл к выводу, что именно этот плагин лучше всего подходит для моих нужд.

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

Ниже приведён пример конфигурации:

<plugins>
    <!-- Этот плагин предоставляет возможность упаковать
         артефакт в uber-JAR файл, включая
         его зависимости, и изменить - т.е. переименовать -
         пакеты некоторых зависимостей. -->
    <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>
                        <!-- Подписанные JAR файлы-->
                        <excludes>
                            <exclude>bouncycastle:bcprov-jdk15</exclude>
                        </excludes>
                    </artifactSet>

                    <transformers>
                        <transformer
                            implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                            <!-- Основной класс -->
                            <mainClass>com.main.MyMainClass</mainClass>
                        </transformer>

                        <!-- Используем трансформеры ресурсов для предотвращения перезаписи файлов -->
                        <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>

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

0

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

Этот код нужно добавить в ваш файл pom.xml. Плагин автоматически объединяет все зависимости вашего проекта в один JAR файл, что упрощает развертывание приложения. Убедитесь, что вы добавили его в правильный раздел <build>.

0

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

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

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь