Перейти к основному содержимому

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

· 7 мин. чтения

1. Обзор

В этом кратком руководстве мы сосредоточимся на упаковке проекта Maven в исполняемый файл Jar.

При создании jar - файла мы обычно хотим легко запустить его, не используя IDE. С этой целью мы обсудим конфигурацию и плюсы и минусы использования каждого из этих подходов для создания исполняемого файла.

2. Конфигурация

Нам не нужны никакие дополнительные зависимости для создания исполняемого файла jar . Нам просто нужно создать проект Maven Java и иметь хотя бы один класс с методом main(…) .

В нашем примере мы создали класс Java с именем ExecutableMavenJar .

Нам также нужно убедиться, что наш pom.xml содержит следующие элементы:

<modelVersion>4.0.0</modelVersion>
<groupId>com.foreach</groupId>
<artifactId>core-java</artifactId>
<version>0.1.0-SNAPSHOT</version>
<packaging>jar</packaging>

Наиболее важным аспектом здесь является тип — чтобы создать исполняемый файл jar , дважды проверьте, что в конфигурации используется тип jar .

Теперь мы можем начать использовать различные решения.

2.1. Ручная настройка

Начнем с ручного подхода с помощью 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 внутри каталога сборки проекта (который обычно является целевой папкой).

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

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>libs/</classpathPrefix>
<mainClass>
com.foreach.executable.ExecutableMavenJar
</mainClass>
</manifest>
</archive>
</configuration>
</plugin>

Наиболее важной частью этого является конфигурация манифеста . Мы добавляем путь к классам со всеми зависимостями (папка libs/ ) и предоставляем информацию об основном классе.

Обратите внимание, что нам нужно указать полное имя класса, что означает, что оно будет включать имя пакета.

Преимущества и недостатки этого подхода:

  • плюсы — прозрачный процесс, где мы можем указать каждый шаг
  • минусы – ручной; зависимости находятся вне окончательного jar , что означает, что наш исполняемый jar будет запускаться только в том случае, если папка libs будет доступна и видна для jar

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

Плагин сборки Apache Maven позволяет пользователям объединять выходные данные проекта вместе с его зависимостями, модулями, документацией сайта и другими файлами в единый работоспособный пакет.

Основная цель плагина сборки — это единственная цель, которая используется для создания всех сборок (все остальные цели устарели и будут удалены в будущем выпуске).

Давайте посмотрим на конфигурацию в 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>
com.foreach.executable.ExecutableMavenJar
</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</execution>
</executions>
</plugin>

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

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

Вывод в нашем примере будет называться core-java-jar-with-dependencies.jar .

  • плюсы — зависимости внутри jar - файла, только один файл
  • минусы — базовый контроль упаковки нашего артефакта, например нет поддержки релокации классов

2.3. Плагин Apache Maven Shade

Плагин Apache Maven Shade предоставляет возможность упаковать артефакт в 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>com.foreach.executable.ExecutableMavenJar</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>

Эта конфигурация состоит из трех основных частей.

Во- первых, <shadedArtifactAttached> помечает все зависимости для упаковки в банку .

Во- вторых, нам нужно указать реализацию трансформатора ; мы использовали стандартный в нашем примере.

Наконец, нам нужно указать основной класс нашего приложения.

Выходной файл будет называться core-java-0.1.0-SNAPSHOT-shaded.jar , где core-java — это имя нашего проекта, за которым следует версия снимка и имя плагина.

  • плюсы — зависимости внутри jar - файла, расширенный контроль над упаковкой нашего артефакта, с затенением и перемещением классов
  • минусы — сложная конфигурация (особенно если мы хотим использовать расширенные функции)

2.4. Плагин One Jar Maven

Другой вариант создания исполняемого файла jar — это проект One Jar.

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

Давайте посмотрим на конфигурацию:

<plugin>
<groupId>com.jolira</groupId>
<artifactId>onejar-maven-plugin</artifactId>
<executions>
<execution>
<configuration>
<mainClass>org.foreach.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 — это коммерческое решение, благодаря которому банки зависимостей не расширяются в файловую систему во время выполнения.

  • плюсы — чистая модель делегирования, позволяет классам находиться на верхнем уровне One Jar, поддерживает внешние jar- файлы и может поддерживать собственные библиотеки .
  • минусы – активно не поддерживается с 2012 года

2.5. Плагин Spring Boot Maven

Наконец, последнее решение, которое мы рассмотрим, — это плагин Spring Boot Maven.

Это позволяет упаковывать исполняемые jar- или военные архивы и запускать приложение «на месте».

Чтобы использовать его, нам нужно использовать как минимум 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>
com.foreach.executable.ExecutableMavenJar
</mainClass>
</configuration>
</execution>
</executions>
</plugin>

Между плагином Spring и другими есть два отличия: цель выполнения называется repackage , а классификатор называется spring-boot .

Обратите внимание, что нам не нужно иметь приложение Spring Boot, чтобы использовать этот плагин.

  • плюсы — зависимости внутри jar - файла, мы можем запускать его в любом доступном месте, расширенный контроль над упаковкой нашего артефакта, с исключением зависимостей из jar - файла и т. д., а также упаковка war - файлов
  • минусы — добавляет потенциально ненужные классы, связанные с Spring и Spring Boot

2.6. Веб-приложение с исполняемым Tomcat

В последней части мы хотим рассказать об автономном веб-приложении, которое упаковано в файл aj ar .

Для этого нам нужно использовать другой плагин, предназначенный для создания исполняемых файлов 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>

Цель установлена как exec -war-only , путь к нашему серверу указан внутри конфигурационного тега с дополнительными свойствами, такими как finalName , charset и т.д.

Чтобы собрать aj ar , мы запускаем man package , что приведет к созданию webapp.jar в нашем целевом каталоге.

Чтобы запустить приложение, мы просто пишем java -jar target/webapp.jar в нашей консоли и пытаемся протестировать его, указав localhost:8080 / в браузере.

  • плюсы — наличие одного файла, простота развертывания и запуска
  • минусы - размер файла намного больше из-за упаковки встроенного дистрибутива Tomcat в файл aw ar

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

<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>

3. Заключение

В этой статье мы описали множество способов создания исполняемого файла jar с помощью различных плагинов Maven.

Полную реализацию этого туториала можно найти в этих проектах GitHub: исполняемый файл jar и исполняемый файл war .

Как проверить? Чтобы скомпилировать проект в исполняемый файл jar , запустите Maven с помощью команды mvn clean package .

Мы надеемся, что эта статья предоставила вам больше информации и поможет вам найти предпочтительный подход в зависимости от ваших потребностей.

Одно быстрое заключительное замечание: мы хотим убедиться, что лицензии банок, которые мы связываем, не запрещают такого рода операции. Как правило, это не так, но об этом стоит подумать.