Java: Как мне создать автономные дистрибутивы проектов на основе Maven?

Я часто сталкиваюсь с дистрибутивами Java-приложений или библиотек, которые используют Maven в качестве инструмента для сборки.

К сожалению, некоторые из них не предоставляют автономных (или распространяемых) банок.

Можно ли создавать приложения на основе Maven таким образом, чтобы результат сборки содержал все зависимости и мог быть перераспределен для работы "из коробки"?

Я попытался построить модуль OCM Джекраббита. По некоторым очень "умным" причинам нет отдельной загружаемой версии.
Поэтому я создал Jackrabbit с Maven (исходный пакет Jackrabbit включает в себя OCM) и получил тот же самый jar, что и в хранилище apache. Баночка не содержит необходимых зависимостей и бесполезна для меня.

6 ответов

Используйте плагин Maven Shade

... но будьте осторожны с ошибками (похожими на описанные ниже в моем ответе), для которых есть объяснение здесь.

Также будьте предельно осторожны с настройкой плагина Shade. Я случайно использовал двойной <configuration> теги один раз, и трансформаторы вообще не применялись, и плагин позволил мне не предупреждать меня.

Не используйте плагин Maven Assembly

assembly:single распакует ваши JAR-файлы зависимостей как есть, и это не может быть тем, что вы хотите. Например, такие вещи, как META-INF/spring.schemas будет переопределен последним JAR-файлом зависимости Spring, который был оценен, и поэтому ваши XSD не будут найдены (конечно, кроме тех, что были в последнем JAR-файле). Вот почему такие системы, как Alfresco, создали свой плагин AMP, который объединяет зависимости внутри lib/ внутри AMP вы строите. Последний поднимает проблемы управления зависимостями, хотя.

Как сказал Доминик, использование плагина сборки поможет. Обычно вы настраиваете его в POM вашего собственного проекта, чтобы собрать и упаковать все необходимые зависимости:

  ...
  <plugin>
    <artifactId>maven-assembly-plugin</artifactId>
    <configuration>
      <descriptorRefs>
        <descriptorRef>jar-with-dependencies</descriptorRef>
      </descriptorRefs>
    </configuration>
  </plugin>
  ...

jar-with-dependencies предопределено плагином сборки и будет включать все зависимости в окончательном пакете (см. документацию здесь).

Если вы не хотите использовать Maven для своего собственного проекта, вам нужно будет изменить POM библиотек и переупаковать их самостоятельно (скачайте исходные коды, добавьте приведенный выше фрагмент в pom.xml и запустите mvn package). Остерегайтесь дублирующихся или несовместимых транзитивных зависимостей, если вы используете несколько библиотек. exclusions может помочь в этом случае (см. документацию здесь).

Вам может повезти с плагином appassembler. В противном случае взгляните на сборочный плагин. Это более гибкий, но более низкий уровень. Если вы используете сборочный плагин, вы можете найти главу о нем в Maven: полное руководство будет полезным.

Как было сказано в нескольких постерах, плагин сборки - это хороший способ создания полного jar-файла со всеми зависимостями проекта. Однако на самом деле вам не нужно изменять файл pom.xml. Просто запустите:

mvn assembly:single -DdescriptorId=jar-with-dependencies

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

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

Его очень легко использовать, и я думаю, этот пример не требует пояснений.

Изменить pom.xml подать и использовать <Embed-Dependency> директивы. Подобный пример можно найти здесь, чтобы вы могли адаптировать его к вашему сценарию.

<Embed-Dependency>*;scope=!test;inline=true</Embed-Dependency>

Я думаю, что это должно сработать.


Вот пример по приведенному выше URL, который, кажется, дает время ожидания.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>br.gov.lexml</groupId>
    <artifactId>toolkit</artifactId>
    <packaging>bundle</packaging>
    <version>3.0</version>
    <parent>
        <artifactId>lexml</artifactId>
        <groupId>br.gov.lexml</groupId>
        <version>1.0</version>
    </parent>
    <build>
        <finalName>Lexml_Toolkit-2.0</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.5</source>
                    <target>1.5</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.felix</groupId>
                <artifactId>maven-bundle-plugin</artifactId>
                <extensions>true</extensions>
                <configuration>
                    <instructions>
                        <!--_include>src/toolkit/resources/META-INF/MANIFEST.MF</_include-->

                        <Export-Package>*;-split-package:=merge-last</Export-Package>
                        <Bundle-Activator>br.gov.lexml.borda.Toolkit</Bundle-Activator>
                        <Bundle-Name>Toolkit</Bundle-Name>
                        <Private-Package />
                        <Embed-Dependency>*;scope=!test;inline=true</Embed-Dependency>
                        <Bundle-ClassPath>.,{maven-dependencies}</Bundle-ClassPath>
                    </instructions>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <dependencies>
        <dependency>
            <groupId>org.apache.xmlbeans</groupId>
            <artifactId>xmlbeans</artifactId>
            <version>2.4.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.xmlbeans</groupId>
            <artifactId>xmlbeans-xmlpublic</artifactId>
            <version>2.4.0</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.15</version>
        </dependency>
        <dependency>
            <groupId>br.gov.lexmlbeans</groupId>
            <artifactId>lexmlbeans</artifactId>
            <version>3.0</version>
        </dependency>
    </dependencies>
</project>
Другие вопросы по тегам