Как создать исполняемый 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.

Надеемся, что данная статья помогла разобраться в этой теме.