Другое

Полное руководство: Исполняемый JAR с Maven

Освойте создание исполняемых JAR с помощью Maven с использованием плагинов Shade, Assembly или Exec JAR. Включает примеры конфигурации и советы по устранению неполадок для бесшовного распространения.

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

Создание исполняемого JAR со всеми зависимостями с помощью Maven

Для создания исполняемого JAR-файла со всеми зависимостями с помощью Maven можно использовать плагины Maven Assembly Plugin, Maven Shade Plugin или Maven Exec JAR Plugin. Наиболее распространенный подход — использование Maven Shade Plugin, который создает “fat JAR” (жирный JAR), упаковывая все зависимости в один исполняемый JAR-файл, что позволяет запускать ваше приложение с помощью простой команды java -jar your-app.jar.

Содержание


Использование Maven Shade Plugin

Maven Shade Plugin — наиболее популярный выбор для создания исполняемых JAR-файлов со всеми включенными зависимостями. Он упаковывает все зависимости в один JAR-файл и также может создавать исполняемый манифест.

xml
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <version>3.5.1</version>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>shade</goal>
                    </goals>
                    <configuration>
                        <transformers>
                            <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                <mainClass>com.example.YourMainClass</mainClass>
                            </transformer>
                        </transformers>
                        <filters>
                            <filter>
                                <artifact>*:*</artifact>
                                <excludes>
                                    <exclude>META-INF/*.SF</exclude>
                                    <exclude>META-INF/*.DSA</exclude>
                                    <exclude>META-INF/*.RSA</exclude>
                                </excludes>
                            </filter>
                        </filters>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

Shade Plugin предлагает дополнительные возможности, такие как объединение сервисных файлов и обработка дублирующихся классов через секцию <filters>.


Использование Maven Assembly Plugin

Maven Assembly Plugin — еще один вариант, который создает дистрибутивные пакеты, включая ваш JAR-файл и все зависимости в структуре каталогов.

xml
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>3.7.1</version>
            <configuration>
                <archive>
                    <manifest>
                        <mainClass>com.example.YourMainClass</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>

Assembly Plugin создает JAR-файл с суффиксом “-with-dependencies”, который включает все зависимости в той же структуре, в которой они появляются в вашем проекте.


Использование Maven Exec JAR Plugin

Maven Exec JAR Plugin проще и специально ориентирован на создание исполняемых JAR-файлов с правильной конфигурацией classpath.

xml
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>3.3.0</version>
            <configuration>
                <archive>
                    <manifest>
                        <addClasspath>true</addClasspath>
                        <classpathPrefix>lib/</classpathPrefix>
                        <mainClass>com.example.YourMainClass</mainClass>
                    </manifest>
                </archive>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <version>3.6.1</version>
            <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>
    </plugins>
</build>

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


Настройка главного класса

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

xml
<manifest>
    <mainClass>com.example.YourMainClass</mainClass>
</manifest>

Кроме того, вы можете указать главный класс в свойствах вашего pom.xml:

xml
<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>11</maven.compiler.source>
    <maven.compiler.target>11</maven.compiler.target>
    <mainClass>com.example.YourMainClass</mainClass>
</properties>

Важно: Убедитесь, что указанный вами главный класс действительно существует в вашем проекте и имеет метод public static void main(String[] args).


Распространенные проблемы и решения

Дублирующиеся классы

При использовании Shade Plugin вы можете столкнуться с конфликтами дублирующихся классов. Вы можете справиться с этим следующим образом:

xml
<configuration>
    <filters>
        <filter>
            <artifact>com.example:conflicting-library</artifact>
            <includes>
                <include>com/example/RequiredClass.class</include>
            </includes>
        </filter>
    </filters>
</configuration>

Исключение файлов безопасности

Shade Plugin может не из-за файлов подписи. Исключите их:

xml
<filters>
    <filter>
        <artifact>*:*</artifact>
        <excludes>
            <exclude>META-INF/*.SF</exclude>
            <exclude>META-INF/*.DSA</exclude>
            <exclude>META-INF/*.RSA</exclude>
        </excludes>
    </filter>
</filters>

Проблемы с конфигурацией манифеста

Убедитесь, что ваш манифест правильно настроен с главным классом. Вы можете проверить содержимое манифеста с помощью:

bash
jar tf your-app.jar | grep META-INF/MANIFEST.MF

Лучшие практики

  1. Используйте Shade Plugin для создания настоящих fat JAR — это самый надежный способ создать один исполняемый JAR-файл со всеми зависимостями.

  2. Исключайте ненужные файлы — удаляйте файлы подписи и записи META-INF для уменьшения размера JAR-файла и избежания конфликтов.

  3. Используйте подходящую версию Java — убедитесь, что ваша конфигурация Maven соответствует версии Java, которую вы используете для разработки.

  4. Тестируйте ваш JAR — всегда тестируйте созданный JAR-файл в целевой среде развертывания перед распространением.

  5. Рассмотрите возможность использования нативных образов — для критически важных по производительности приложений рассмотрите возможность использования GraalVM для создания нативных исполняемых файлов вместо JAR.

  6. Используйте управление зависимостями — правильно управляйте вашими зависимостями в секции dependencyManagement вашего pom.xml для избежания конфликтов версий.


Сборка и запуск JAR

Сборка JAR

После настройки соберите ваш исполняемый JAR-файл с помощью Maven:

bash
mvn clean package

Сгенерированный JAR-файл обычно будет находиться в каталоге target/ с именем вроде your-app-1.0.0.jar или your-app-1.0.0-jar-with-dependencies.jar.

Запуск JAR

Запустите ваш исполняемый JAR-файл с помощью:

bash
java -jar target/your-app-1.0.0-jar-with-dependencies.jar

Проверка зависимостей

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

bash
jar tf target/your-app-1.0.0-jar-with-dependencies.jar | head -20

Для более детальной проверки:

bash
jar -tf target/your-app-1.0.0-jar-with-dependencies.jar | grep com/example

Заключение

Создание исполняемого JAR-файла со всеми включенными зависимостями с помощью Maven является простым при правильной настройке плагина. Maven Shade Plugin, как правило, является лучшим выбором для создания настоящих fat JAR, в то время как Assembly Plugin предлагает больше гибкости в вариантах упаковки, а Exec JAR Plugin предоставляет более простой подход с отдельными каталогами для зависимостей.

Ключевые рекомендации:

  • Используйте Maven Shade Plugin для большинства приложений, требующих одного исполняемого файла
  • Всегда правильно настраивайте главный класс в вашем манифесте
  • Тщательно тестируйте ваш JAR-файл перед распространением
  • Учитывайте компромиссы между разными подходами в зависимости от ваших потребностей в развертывании

Следуя этим практикам, вы можете легко распространять ваши Java-приложения как самодостаточные исполняемые JAR-файлы, которые работают на любой системе с установленным Java.

Источники

  1. Документация Apache Maven Shade Plugin
  2. Документация Apache Maven Assembly Plugin
  3. Документация Apache Maven JAR Plugin
  4. Лучшие практики для Java Executable JAR
Авторы
Проверено модерацией
Модерация