Frage Wie kann ich eine ausführbare JAR mit Abhängigkeiten mit Maven erstellen?


Ich möchte mein Projekt in einer einzigen ausführbaren JAR für die Verteilung verpacken.

Wie kann ich ein Maven-Projekt alle Abhängigkeits-JARs in meine Ausgabe-JAR packen?


1939
2018-02-22 08:43


Ursprung


Antworten:


<build>
  <plugins>
    <plugin>
      <artifactId>maven-assembly-plugin</artifactId>
      <configuration>
        <archive>
          <manifest>
            <mainClass>fully.qualified.MainClass</mainClass>
          </manifest>
        </archive>
        <descriptorRefs>
          <descriptorRef>jar-with-dependencies</descriptorRef>
        </descriptorRefs>
      </configuration>
    </plugin>
  </plugins>
</build>

und du machst es mit

mvn clean compile assembly:single

Kompilierungsziel sollte vor der Assembly hinzugefügt werden: single oder sonst ist der Code in Ihrem eigenen Projekt nicht enthalten.

Weitere Details finden Sie in Kommentaren.


Üblicherweise ist dieses Ziel an eine Build-Phase gebunden, die automatisch ausgeführt wird. Dadurch wird sichergestellt, dass das JAR bei der Ausführung erstellt wird mvn install oder Durchführen einer Bereitstellung / Freigabe.

<plugin>
  <artifactId>maven-assembly-plugin</artifactId>
  <configuration>
    <archive>
      <manifest>
        <mainClass>fully.qualified.MainClass</mainClass>
      </manifest>
    </archive>
    <descriptorRefs>
      <descriptorRef>jar-with-dependencies</descriptorRef>
    </descriptorRefs>
  </configuration>
  <executions>
    <execution>
      <id>make-assembly</id> <!-- this is used for inheritance merges -->
      <phase>package</phase> <!-- bind to the packaging phase -->
      <goals>
        <goal>single</goal>
      </goals>
    </execution>
  </executions>
</plugin>

1864
2017-12-01 10:46



Sie können das Abhängigkeits-Plugin verwenden, um alle Abhängigkeiten vor der Paketphase in einem separaten Verzeichnis zu generieren und dieses dann in den Klassenpfad des Manifests einzufügen:

<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}/lib</outputDirectory>
                <overWriteReleases>false</overWriteReleases>
                <overWriteSnapshots>false</overWriteSnapshots>
                <overWriteIfNewer>true</overWriteIfNewer>
            </configuration>
        </execution>
    </executions>
</plugin>
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <configuration>
        <archive>
            <manifest>
                <addClasspath>true</addClasspath>
                <classpathPrefix>lib/</classpathPrefix>
                <mainClass>theMainClass</mainClass>
            </manifest>
        </archive>
    </configuration>
</plugin>

Alternativ verwenden ${project.build.directory}/classes/lib als OutputDirectory, um alle jar-Dateien in das Hauptjar zu integrieren, aber dann müssen Sie benutzerdefinierten Classloading-Code hinzufügen, um die Jars zu laden.


294
2018-06-02 03:01



Ich habe über verschiedene Wege gebloggt.

Sehen Ausführbare Jar mit Apache Maven (WordPress)

oder ausführbares-jar-with-maven-example (GitHub)

Anmerkungen

Diese Vor- und Nachteile werden von Stephan.


Für manuelle Bereitstellung

  • Pros
  • Nachteile
    • Abhängigkeiten sind außerhalb des endgültigen Jar.

Kopieren Sie Abhängigkeiten in ein bestimmtes Verzeichnis

<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}/${project.build.finalName}.lib</outputDirectory>
      </configuration>
    </execution>
  </executions>
</plugin>

Mach das Jar ausführbar und Classpath Aware

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-jar-plugin</artifactId>
  <configuration>
    <archive>
      <manifest>
        <addClasspath>true</addClasspath>
        <classpathPrefix>${project.build.finalName}.lib/</classpathPrefix>
        <mainClass>${fully.qualified.main.class}</mainClass>
      </manifest>
    </archive>
  </configuration>
</plugin>

An diesem Punkt der jar ist tatsächlich mit externen Klassenpfadelementen ausführbar.

$ java -jar target/${project.build.finalName}.jar

Machen Sie Deployable Archives

Das jar Datei ist nur mit dem Geschwister ausführbar ...lib/ Verzeichnis. Wir müssen Archive erstellen, die mit dem Verzeichnis und seinem Inhalt bereitgestellt werden.

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-antrun-plugin</artifactId>
  <executions>
    <execution>
      <id>antrun-archive</id>
      <phase>package</phase>
      <goals>
        <goal>run</goal>
      </goals>
      <configuration>
        <target>
          <property name="final.name" value="${project.build.directory}/${project.build.finalName}"/>
          <property name="archive.includes" value="${project.build.finalName}.${project.packaging} ${project.build.finalName}.lib/*"/>
          <property name="tar.destfile" value="${final.name}.tar"/>
          <zip basedir="${project.build.directory}" destfile="${final.name}.zip" includes="${archive.includes}" />
          <tar basedir="${project.build.directory}" destfile="${tar.destfile}" includes="${archive.includes}" />
          <gzip src="${tar.destfile}" destfile="${tar.destfile}.gz" />
          <bzip2 src="${tar.destfile}" destfile="${tar.destfile}.bz2" />
        </target>
      </configuration>
    </execution>
  </executions>
</plugin>

Jetzt hast du target/${project.build.finalName}.(zip|tar|tar.bz2|tar.gz) welche enthält jeweils die jar und lib/*.


Apache Maven Assembly Plugin

  • Pros
  • Nachteile
    • Keine Unterstützung für Klassenumzug (Verwenden Sie maven-shade-plugin, wenn eine Klassenverschiebung erforderlich ist).
<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>${fully.qualified.main.class}</mainClass>
          </manifest>
        </archive>
        <descriptorRefs>
          <descriptorRef>jar-with-dependencies</descriptorRef>
        </descriptorRefs>
      </configuration>
    </execution>
  </executions>
</plugin>

Du hast target/${project.bulid.finalName}-jar-with-dependencies.jar.


Apache Maven Schatten-Plugin

  • Pros
  • Nachteile
<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>${fully.qualified.main.class}</mainClass>
          </transformer>
        </transformers>
      </configuration>
    </execution>
  </executions>
</plugin>

Du hast target/${project.build.finalName}-shaded.jar.


onejar-maven-plugin

  • Pros
  • Nachteile
    • Seit 2012 nicht mehr aktiv unterstützt.
<plugin>
  <!--groupId>org.dstovall</groupId--> <!-- not available on the central -->
  <groupId>com.jolira</groupId>
  <artifactId>onejar-maven-plugin</artifactId>
  <executions>
    <execution>
      <configuration>
        <mainClass>${fully.qualified.main.class}</mainClass>
        <attachToBuild>true</attachToBuild>
        <!-- https://code.google.com/p/onejar-maven-plugin/issues/detail?id=8 -->
        <!--classifier>onejar</classifier-->
        <filename>${project.build.finalName}-onejar.${project.packaging}</filename>
      </configuration>
      <goals>
        <goal>one-jar</goal>
      </goals>
    </execution>
  </executions>
</plugin>

Spring Boot Maven Plugin

  • Pros
  • Nachteile
    • Fügen Sie potenziell unnötige Spring und Spring Boot-bezogene Klassen hinzu.
<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>${fully.qualified.main.class}</mainClass>
      </configuration>
    </execution>
  </executions>
</plugin>

Du hast target/${project.bulid.finalName}-spring-boot.jar.


134
2018-02-26 04:31



Wir nehmen die Antwort von Unanswered entgegen und formatieren sie neu:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <configuration>
                <archive>
                    <manifest>
                        <addClasspath>true</addClasspath>
                        <mainClass>fully.qualified.MainClass</mainClass>
                    </manifest>
                </archive>
            </configuration>
        </plugin>
        <plugin>
            <artifactId>maven-assembly-plugin</artifactId>
            <configuration>
                <descriptorRefs>
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
            </configuration>
        </plugin>
    </plugins>
</build>

Als Nächstes würde ich empfehlen, dies zu einem natürlichen Teil Ihres Builds zu machen, anstatt etwas explizit zu nennen. Um dies zu einem integralen Bestandteil Ihres Builds zu machen, fügen Sie dieses Plugin zu Ihrem hinzu pom.xml und binden Sie es an die package Lebenszyklus-Ereignis. Wie auch immer, ein Problem ist, dass Sie die anrufen müssen assembly:single Ziel, wenn Sie dies in Ihre pom.xml setzen, während Sie "assembly: assembly" aufrufen würden, wenn Sie es manuell über die Befehlszeile ausführen.

<project>
  [...]
  <build>
      <plugins>
          <plugin>
              <artifactId>maven-assembly-plugin</artifactId>
              <configuration>
                  <archive>
                      <manifest>
                          <addClasspath>true</addClasspath>
                          <mainClass>fully.qualified.MainClass</mainClass>
                      </manifest>
                  </archive>
                  <descriptorRefs>
                      <descriptorRef>jar-with-dependencies</descriptorRef>
                  </descriptorRefs>
              </configuration>
              <executions>
                  <execution>
                      <id>make-my-jar-with-dependencies</id>
                      <phase>package</phase>
                      <goals>
                          <goal>single</goal>
                      </goals>
                  </execution>
              </executions>
          </plugin>
      [...]
      </plugins>
    [...]
  </build>
</project>

122
2017-09-22 15:20



Verwenden Sie das Maven-Schatten-Plugin, um alle Abhängigkeiten in ein Uber-Jar zu packen. Es kann auch verwendet werden, um ein ausführbares jar zu erstellen, indem die Hauptklasse angegeben wird. Nach dem Versuch, maven-assembly und maven-jar zu verwenden, stellte ich fest, dass dieses Plugin am besten zu meinen Bedürfnissen passte.

Ich fand dieses Plugin besonders nützlich, da es den Inhalt bestimmter Dateien zusammenführt, anstatt sie zu überschreiben. Dies ist erforderlich, wenn Ressourcendateien in den Gläsern denselben Namen haben und das Plugin versucht, alle Ressourcendateien zu packen

Siehe Beispiel unten

      <plugins>
    <!-- This plugin provides the capability to package the artifact in an uber-jar, including its dependencies and to shade - i.e. rename - the packages of some of the dependencies. -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <version>1.4</version>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>shade</goal>
                    </goals>
                    <configuration>
                        <artifactSet>
                        <!-- signed jars-->
                            <excludes>
                                <exclude>bouncycastle:bcprov-jdk15</exclude>
                            </excludes>
                        </artifactSet>

                         <transformers>
                            <transformer
                                implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                <!-- Main class -->
                                <mainClass>com.main.MyMainClass</mainClass>
                            </transformer>
                            <!-- Use resource transformers to prevent file overwrites -->
                            <transformer 
                                 implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                                <resource>properties.properties</resource>
                            </transformer>
                            <transformer
                                implementation="org.apache.maven.plugins.shade.resource.XmlAppendingTransformer">
                                <resource>applicationContext.xml</resource>
                            </transformer>
                            <transformer
                                implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                                <resource>META-INF/cxf/cxf.extension</resource>
                            </transformer>
                            <transformer
                                implementation="org.apache.maven.plugins.shade.resource.XmlAppendingTransformer">
                                <resource>META-INF/cxf/bus-extensions.xml</resource>
                            </transformer>
                     </transformers>
                    </configuration>
                </execution>
            </executions>
        </plugin>

    </plugins>

91
2018-03-13 20:55



Lange benutzt die Maven Assembly Plugin, aber ich konnte keine Lösung für das Problem finden "already added, skipping". Jetzt benutze ich ein anderes Plugin - onejar-maven-plugin. Beispiel unten (mvn package Glas bauen):

<plugin>
    <groupId>org.dstovall</groupId>
    <artifactId>onejar-maven-plugin</artifactId>
    <version>1.3.0</version>
    <executions>
        <execution>
            <configuration>
                <mainClass>com.company.MainClass</mainClass>
            </configuration>
            <goals>
                <goal>one-jar</goal>
            </goals>
        </execution>
    </executions>
</plugin>

Sie müssen ein Repository für dieses Plugin hinzufügen:

<pluginRepositories>
    <pluginRepository>
        <id>onejar-maven-plugin.googlecode.com</id>
        <url>http://onejar-maven-plugin.googlecode.com/svn/mavenrepo</url>
    </pluginRepository>
</pluginRepositories>

15
2017-10-13 12:16



Sie können maven-dependency-plugin verwenden, aber die Frage war, wie man eine ausführbare JAR erstellt. Um dies zu tun, muss Matthew Franglen die folgende Änderung vornehmen (übrigens benötigt die Verwendung des Abhängigkeits-Plugins länger, wenn man mit einem sauberen Ziel beginnt):

<build>
    <plugins>
        <plugin>
            <artifactId>maven-jar-plugin</artifactId>
            <configuration>
                <archive>
                    <manifest>
                        <mainClass>fully.qualified.MainClass</mainClass>
                    </manifest>
                </archive>
            </configuration>
        </plugin>
        <plugin>
            <artifactId>maven-dependency-plugin</artifactId>
            <executions>
                <execution>
                    <id>unpack-dependencies</id>
                    <phase>package</phase>
                    <goals>
                        <goal>unpack-dependencies</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
    <resources>
        <resource>
            <directory>${basedir}/target/dependency</directory>
        </resource>
    </resources>
</build>

14
2018-03-11 15:12



Eine weitere Option, wenn Sie wirklich die anderen JAR-Inhalte in Ihrer einzigen resultierenden JAR-Datei neu packen möchten, ist die Maven Assembly Plugin. Es entpackt und packt dann alles in ein Verzeichnis via <unpack>true</unpack>. Dann hätten Sie einen zweiten Durchlauf, der es in ein massives JAR integrierte.

Eine weitere Option ist das OneJar-Plugin. Dies führt die obigen Umpackaktionen alle in einem Schritt durch.


13
2017-08-13 18:23



Sie können Folgendes zu Ihrem hinzufügen pom.xml:

<build>
<defaultGoal>install</defaultGoal>
<plugins>
  <plugin>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>2.3.2</version>
    <configuration>
      <source>1.6</source>
      <target>1.6</target>
    </configuration>
  </plugin>
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>2.3.1</version>
    <configuration>
      <archive>
        <manifest>
          <addClasspath>true</addClasspath>
          <mainClass>com.mycompany.package.MainClass</mainClass>
        </manifest>
      </archive>
    </configuration>
  </plugin>
  <plugin>
    <artifactId>maven-assembly-plugin</artifactId>
    <configuration>
      <descriptorRefs>
        <descriptorRef>jar-with-dependencies</descriptorRef>
      </descriptorRefs>
      <archive>
        <manifest>
          <mainClass>com.mycompany.package.MainClass</mainClass>
        </manifest>
      </archive>
    </configuration>
    <executions>
      <execution>
        <id>make-my-jar-with-dependencies</id>
        <phase>package</phase>
        <goals>
          <goal>single</goal>
        </goals>
      </execution>
    </executions>
  </plugin>
</plugins>
</build>

Danach müssen Sie über die Konsole in das Verzeichnis wechseln, in dem sich die pom.xml befindet. Dann müssen Sie ausführen MVN Montage: Single und dann wird hoffentlich Ihre ausführbare JAR-Datei mit Abhängigkeiten erstellt. Sie können dies überprüfen, wenn Sie mit dem Zielverzeichnis () wechseln CD ./ Ziel und starten Sie Ihr Glas mit einem Befehl ähnlich java -jar mavenproject1-1.0-SNAPSHOT-jar-mit-abhängigkeiten.jar.

Ich habe das mit getestet Apache Maven 3.0.3.


11
2017-11-26 14:17



Du könntest das kombinieren maven-shade-plugin und maven-jar-plugin.

  • Das maven-shade-plugin Packt Ihre Klassen und alle Abhängigkeiten in einer einzigen JAR-Datei.
  • Konfigurieren Sie die maven-jar-plugin um die Hauptklasse Ihres ausführbaren jars anzugeben (siehe Richten Sie den Klassenpfad ein, Kapitel "Mach das Jar Executable").

Beispiel POM-Konfiguration für maven-jar-plugin:

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>2.3.2</version>
            <configuration>
                <archive>
                    <manifest>
                        <addClasspath>true</addClasspath>
                        <mainClass>com.example.MyMainClass</mainClass>
                    </manifest>
                </archive>
            </configuration>
        </plugin>

Erstellen Sie abschließend das ausführbare jar, indem Sie Folgendes aufrufen:

mvn clean package shade:shade

8
2017-11-23 20:28



Ich habe jede dieser Antworten durchgesehen, um einen fetten ausführbaren Krug zu erstellen, der alle Abhängigkeiten enthält und keiner von ihnen hat richtig funktioniert. Die Antwort ist das Schatten-Plugin, das sehr einfach und unkompliziert ist.

    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-shade-plugin</artifactId>
      <version>2.3</version>
      <executions>
         <!-- Run shade goal on package phase -->
        <execution>
        <phase>package</phase>
        <goals>
            <goal>shade</goal>
        </goals>
        <configuration>
          <transformers>
             <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                <mainClass>path.to.MainClass</mainClass>
             </transformer>
          </transformers>
        </configuration>
          </execution>
      </executions>
    </plugin>

Beachten Sie, dass Ihre Abhängigkeiten einen Bereich von Kompilieren oder Laufzeit haben müssen, damit dies ordnungsgemäß funktioniert.

Dieses Beispiel stammt von mkyong.com


8
2017-09-09 13:37