Как создать исполняемый JAR с помощью Maven
Введение
В этой статье мы рассмотрим упаковку Maven- проекта в файл Jar. Выясним преимущества и недостатки каждого из подходов, применяемых для создания исполняемого файла.
Конфигурация
Чтобы создать исполняемый файл jar, не требуются дополнительные зависимости. Нам нужно просто создать Java-проект Maven с одним классом и методом main(…).
В приведенном ниже примере мы создаем Java-класс ExecutableMavenJar. Для этого в файл pom.xml нужно добавить следующие элементы:
<modelVersion>4.0.0</modelVersion>
<groupId>com.baeldung</groupId>
<artifactId>core-java</artifactId>
<version>0.1.0-SNAPSHOT</version>
<packaging>jar</packaging>
Удостоверьтесь в том, что в конфигурации задан тип jar. Теперь можно приступить к реализации каждого из подходов.
Ручная настройка
Для этого мы используем плагин 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}/libs
</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
Сначала мы задаем цель copy-dependencies, что указывает Maven скопировать эти зависимости в заданный outputDirectory.
В данном случае мы создадим папку с именем libs внутри каталога сборки проекта (обычно это папка target).
Затем мы создаем исполняемый файл jar с указанными путями к классам и со ссылкой на зависимости, скопированные на первом шаге:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>libs/</classpathPrefix>
<mainClass>
org.baeldung.executable.ExecutableMavenJar
</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
Наиболее важной частью приведенного выше кода является конфигурация manifest. В ней мы добавляем classpath со всеми зависимостями (папка libs/), а также предоставляем информацию о главном классе.
Преимущества и недостатки этого подхода:
- Преимущества - прозрачный процесс, в рамках которого можно прописать каждый шаг.
- Недостатки - зависимости находятся вне финального файла jar. Поэтому он будет работать только, если папка libs будет доступна и видима для jar-файла.
Apache Maven Assembly Plugin
Плагин Apache Maven Assembly позволяет объединять выходные данные проекта вместе с зависимостями, модулями, документацией и другими файлами в единый пакет.
Основной целью в плагине сборки является single. Она используется для создания любых сборок. Остальные цели устарели и будут удалены в следующей версии плагина.
Рассмотрим конфигурацию, заданную в файле pom.xml:
<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>
org.baeldung.executable.ExecutableMavenJar
</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</execution>
</executions>
</plugin>
Как и при ручной настройке, сначала нужно предоставить информацию о главном классе. Но плагин автоматически скопирует все необходимые зависимости в файл JAR .
В descriptorRefs мы указали имя, которое будет добавлено к имени проекта. В нашем случае – это core-java-jar-with-dependencies.jar.
- Преимущества – зависимости хранятся внутри jar-файла.
- Недостатки - упрощенный контроль упаковки артефакта. Например, нет поддержки перемещения классов.
Apache Maven Shade Plugin
Плагин позволяет упаковывать артефакт в uber-jar, который включает в себя все зависимости, необходимые для запуска проекта. Кроме того, он поддерживает переименование пакетов некоторых зависимостей.
Рассмотрим приведенную ниже конфигурацию:
<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>org.baeldung.executable.ExecutableMavenJar</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
В этой конфигурации <shadedArtifactAttached> отмечает все зависимости, которые должны быть упакованы в файл jar.
Затем нам нужно указать реализацию трансформатора. В текущем примере мы использовали стандартную версию. В конце задаем основной класс приложения.
Выходной файл получит название core-java-0.1.0-SNAPSHOT-shaded.jar, где core-java - это имя проекта. За ним следуют версия и имя плагина.
- Преимущества - зависимости внутри jar-файла, расширенный контроль упаковки артефакта.
- Недостатки - сложная конфигурация (особенно если необходимо использовать расширенные функции).
One Jar Maven Plugin
Плагин предоставляет собственный загрузчик, который знает, как загружать классы и ресурсы из jar-файлов архива.
Рассмотрим приведенную ниже конфигурацию:
<plugin>
<groupId>com.jolira</groupId>
<artifactId>onejar-maven-plugin</artifactId>
<executions>
<execution>
<configuration>
<mainClass>org.baeldung.executable.
ExecutableMavenJar</mainClass>
<attachToBuild>true</attachToBuild>
<filename>
${project.build.finalName}.${project.packaging}
</filename>
</configuration>
<goals>
<goal>one-jar</goal>
</goals>
</execution>
</executions>
</plugin>
Сначала необходимо указать основной класс и прикрепить все зависимости сборки, используя для этого attachToBuild = true .
Также необходимо задать имя файла для вывода. Цель Maven - это one-jar.
В One Jar зависимости jar не будут расширены в файловую систему во время выполнения.
- Преимущества - позволяет классам располагаться на верхнем уровне One Jar. Плагин поддерживает внешние jar и собственные библиотеки.
- Недостатки – не обновляется с 2012 года.
Плагин Spring Boot Maven
Плагин позволяет упаковывать исполняемые архивы jar или war и запустить приложение «на месте». Он поддерживает Maven версии 3.2 или выше. Более подробное описание плагина доступно здесь.
Рассмотрим приведенную ниже конфигурацию:
<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>
org.baeldung.executable.ExecutableMavenJar
</mainClass>
</configuration>
</execution>
</executions>
</plugin>
Между Spring и другими плагинами есть два существенных отличия: цель выполнения называется repackage, а классификатор - spring-boot . Обратите внимание, что плагин можно использовать без Spring Boot.
- Достоинства – зависимости располагаются внутри jar- файла, его можно запускать в любом доступном месте, улучшенный контроль упаковки артефакта, исключение зависимостей из jar-файла и упаковка war файлов.
- Недостатки - добавляет ненужные классы, связанные с Spring и Spring Boot.
Веб-приложение с исполняемым Tomcat
В последней части статьи мы рассмотрим упаковку автономного веб-приложения в jar-файл. Но для этого понадобится другой плагин.
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.0</version>
<executions>
<execution>
<id>tomcat-run</id>
<goals>
<goal>exec-war-only</goal>
</goals>
<phase>package</phase>
<configuration>
<path>/</path>
<enableNaming>false</enableNaming>
<finalName>webapp.jar</finalName>
<charset>utf-8</charset>
</configuration>
</execution>
</executions>
</plugin>
Чтобы создать jar-файл, запустите man package, который создаст webapp.jar в каталоге target.
Чтобы запустить приложение, просто введите в консоли: java -jar target / webapp.jar и проверьте результат по адресу: localhost:8080/.
- Преимущества - наличие одного файла, простота развертывания и запуска.
- Недостатки - размер файла намного больше.
Обратите внимание на то, что это последняя версия данного плагина, поддерживающая сервер Tomcat7. Чтобы избежать ошибок, обязательно убедитесь в том, что для зависимости Servlets scope задано значение provided. Иначе во время выполнения jar-файла возникнет конфликт:
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
Заключение
В этой статье мы рассмотрели несколько способов создания исполняемого jar-файла с помощью различных плагинов Maven. Полную реализацию этого руководства вы сможете найти в проектах, опубликованных на Github:
Исполняемый jar
Исполняемый war
Как проверить? Чтобы скомпилировать проект в исполняемый файл jar, запустите Maven с помощью команды mvn clean package.
Надеемся, что данная статья помогла разобраться в этой теме.