wake-up-neo.com

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

Ich möchte mein Projekt für die Verteilung in eine einzelne ausführbare JAR packen.

Wie kann ich aus einem Maven-Projektpaket alle Abhängigkeits-JARs in meine Ausgabe-JAR machen?

2221
soemirno
<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

Das Kompilierungsziel sollte vor dem Zusammenbau hinzugefügt werden: einzeln oder anderweitig ist der Code für Ihr eigenes Projekt nicht enthalten.

Weitere Details finden Sie in den Kommentaren.


In der Regel ist dieses Ziel an eine Build-Phase gebunden, die automatisch ausgeführt wird. Dies stellt sicher, dass die JAR erstellt wird, wenn mvn install ausgeführt oder eine Bereitstellung/Freigabe durchgeführt wird.

<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>
2176
IAdapter

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 aufzunehmen:

<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 können Sie ${project.build.directory}/classes/lib als OutputDirectory verwenden, um alle JAR-Dateien in die Haupt-JAR-Datei zu integrieren. Anschließend müssen Sie jedoch benutzerdefinierten Klassenlade-Code hinzufügen, um die JAR-Dateien zu laden.

326
André Aronsen

Ich habe über verschiedene Möglichkeiten gebloggt.

Siehe Ausführbare Jar mit Apache Maven (WordPress)

oder ausführbares-jar-mit-maven-Beispiel (GitHub)

Anmerkungen

Diese Vor- und Nachteile werden von Stephan bereitgestellt.


Für die manuelle Bereitstellung

  • Vorteile
  • Nachteile
    • Abhängigkeiten sind aus dem letzten Glas.

Abhängigkeiten in ein bestimmtes Verzeichnis kopieren

<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>

Machen Sie das Jar Executable 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>

Zu diesem Zeitpunkt ist jar tatsächlich mit externen Klassenpfadelementen ausführbar.

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

Bereitstellbare Archive erstellen

Die Datei jar kann nur mit dem Verzeichnis sibling ...lib/ ausgeführt werden. Wir müssen Archive erstellen, um sie mit dem Verzeichnis und seinem Inhalt bereitzustellen.

<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 haben Sie target/${project.build.finalName}.(Zip|tar|tar.bz2|tar.gz), die jeweils jar und lib/* enthalten.


Apache Maven Assembly Plugin

  • Vorteile
  • Nachteile
    • Keine Unterstützung für Klassenumzüge (verwenden Sie das Maven-Shade-Plugin, wenn Klassenumzüge erforderlich sind).
<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>

Sie haben target/${project.bulid.finalName}-jar-with-dependencies.jar.


Apache Maven Shade Plugin

  • Vorteile
  • 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>

Sie haben target/${project.build.finalName}-shaded.jar.


onejar-maven-plugin

  • Vorteile
  • Nachteile
    • Wird seit 2012 nicht 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

  • Vorteile
  • Nachteile
    • Fügen Sie potenziell nicht benötigte Spring- und Spring Boot-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>

Sie haben target/${project.bulid.finalName}-spring-boot.jar.

191
Jin Kwon

Ausgehend von der Antwort von Unbeantwortet und ihrer Neuformatierung haben wir:

<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 Bestandteil Ihres Builds zu machen, anstatt es explizit aufzurufen. Um dies zu einem integralen Bestandteil Ihres Builds zu machen, fügen Sie dieses Plugin Ihrem pom.xml hinzu und binden Sie es an das package -Lebenszyklusereignis. Ein Problem ist jedoch, dass Sie das Assembly:single -Ziel aufrufen müssen, wenn Sie dies in Ihre pom.xml einfügen, 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>
133

Verwenden Sie das Maven-Shade-Plugin, um alle Abhängigkeiten in ein einziges Uber-Jar zu packen. Es kann auch zum Erstellen einer ausführbaren JAR-Datei verwendet werden, indem die Hauptklasse angegeben wird. Nachdem ich versucht hatte, maven-Assembly und maven-jar zu verwenden, stellte ich fest, dass dieses Plugin meinen Anforderungen am besten entsprach.

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

Siehe folgendes Beispiel

      <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>
96
Vijay Katam

Habe lange das maven Assembly Plugin benutzt, aber ich konnte keine Lösung für das Problem mit "already added, skipping" finden. Jetzt verwende ich ein anderes Plugin - onejar-maven-plugin . Beispiel unten (_mvn package_ Build Jar):

_<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 das 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>
_
19
marioosh

Sie können maven-dependency-plugin verwenden, aber die Frage war, wie man eine ausführbare JAR erstellt. Um dies zu tun, muss die Antwort von Matthew Franglen wie folgt geändert werden (übrigens dauert die Verwendung des Abhängigkeits-Plugins länger, wenn von einem sauberen Ziel ausgegangen wird):

<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>
17
user189057

Eine weitere Option, wenn Sie den Inhalt der anderen JARs in Ihrer einzigen resultierenden JAR wirklich neu packen möchten, ist das Maven Assembly-Plugin . Es entpackt und packt dann alles über <unpack>true</unpack> in ein Verzeichnis. Dann hätten Sie einen zweiten Durchgang, der es in eine massive JAR baute.

Eine andere Option ist das OneJar-Plugin . Dadurch werden die oben genannten Aktionen zum erneuten Verpacken in einem Schritt ausgeführt.

15

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

<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>

Anschließend muss über die Konsole in das Verzeichnis gewechselt werden, in dem sich die pom.xml befindet. Dann müssen Sie mvn Assembly: single ausführen und dann wird hoffentlich Ihre ausführbare JAR-Datei mit Abhängigkeiten erstellt. Sie können dies überprüfen, indem Sie mit cd ./target in das Ausgabeverzeichnis (target) wechseln und Ihr jar mit einem Befehl starten, der Java -jar mavenproject1-1.0-SNAPSHOT-jar-with) ähnelt -dependencies.jar.

Ich habe das mit Apache Maven 3.0. getestet.

13

Ich ging jede dieser Antworten durch und suchte nach einem fetten ausführbaren Glas, das alle Abhängigkeiten enthielt, und keines von ihnen funktionierte richtig. Die Antwort ist das Schatten-Plugin, es ist sehr einfach und unkompliziert.

    <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 über einen Kompilierungs- oder Laufzeitbereich verfügen müssen, damit dies ordnungsgemäß funktioniert.

Dieses Beispiel stammt von mkyong.com

11
dsutherland

Sie können den maven-shade-plugin und den maven-jar-plugin kombinieren.

  • Der maven-shade-plugin packt Ihre Klassen und alle Abhängigkeiten in eine einzige JAR-Datei.
  • Konfigurieren Sie den maven-jar-plugin, um die Hauptklasse Ihrer ausführbaren JAR-Datei anzugeben (siehe Set Up The Classpath , Kapitel "Make The Jar Executable").

Beispiel einer 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 die ausführbare JAR-Datei, indem Sie Folgendes aufrufen:

mvn clean package shade:shade
11
Oliver

Sie können das Maven-Shadow-Plugin verwenden, um ein Uber-Jar wie unten zu erstellen

<plugin>
    <groupId>org.Apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>shade</goal>
            </goals>
        </execution>
    </executions>
</plugin>
10
Minisha

Hier ist ein ausführbares Jar-Plugin für Maven, das wir bei Credit Karma verwenden. Es erstellt eine JAR-JAR-Datei mit einem Klassenladeprogramm, mit dem Klassen aus verschachtelten JAR-Dateien geladen werden können. Auf diese Weise können Sie in dev und prod denselben Klassenpfad verwenden und dennoch alle Klassen in einer einzelnen signierten JAR-Datei speichern.

https://github.com/creditkarma/maven-exec-jar-plugin

Und hier ist ein Blog-Beitrag mit Details zum Plugin und warum wir es erstellt haben: https://engineering.creditkarma.com/general-engineering/new-executable-jar-plugin-available-Apache-maven/ =

9
jchavannes

Ken Liu hat meiner Meinung nach Recht. Mit dem Maven-Abhängigkeits-Plugin können Sie alle Abhängigkeiten erweitern, die Sie dann als Ressourcen behandeln können. Auf diese Weise können Sie sie in das Artefakt main aufnehmen. Durch die Verwendung des Assembly-Plugins wird ein sekundäres Artefakt erstellt, das möglicherweise nur schwer geändert werden kann. In meinem Fall wollte ich benutzerdefinierte Manifesteinträge hinzufügen. Mein Pom endete als:

<project>
 ...
 <build>
  <plugins>
   <plugin>
    <groupId>org.Apache.maven.plugins</groupId>
    <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>
    <targetPath>/</targetPath>
   </resource>
  </resources>
 </build>
 ...
</project>
9

Es sollte so sein:

<plugin>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
        <execution>
            <id>unpack-dependencies</id>
            <phase>generate-resources</phase>
            <goals>
                <goal>unpack-dependencies</goal>
            </goals>
        </execution>
    </executions>
</plugin>

Das Entpacken muss in der Phase "Ressourcen generieren" erfolgen, da in der Paketphase keine Ressourcen enthalten sind. Versuchen Sie es mit einem sauberen Paket und Sie werden sehen.

9
kac-ani

Verwenden Sie onejar plugin , um es als eine ausführbare JAR-Datei zu erstellen, in der alle Dependancy-JARs enthalten sind. Das hat mein ähnliches Problem gelöst. Als das Assembly-Plugin verwendet wurde, wurden alle Dependancy-Jars in den Quellordner entpackt und als JAR neu gepackt. Alle ähnlichen Implementierungen, die ich in meinem Code hatte und die gleichen Klassennamen hatten, wurden überschrieben. onejar ist hier eine einfache Lösung.

7
AmilaR

Problem beim Auffinden der gemeinsam genutzten Assembly-Datei mit maven-Assembly-plugin-2.2.1?

Verwenden Sie den Konfigurationsparameter descriptorId anstelle der Parameter descriptors/descriptor oder descriptorRefs/descriptorRef.

Keiner von beiden macht das, was Sie brauchen: Suchen Sie nach der Datei im Klassenpfad. Natürlich müssen Sie das Paket hinzufügen, in dem sich die gemeinsam genutzte Assembly im Klassenpfad von maven-Assembly-plugin befindet (siehe unten). Wenn Sie Maven 2.x (nicht Maven 3.x) verwenden, müssen Sie diese Abhängigkeit möglicherweise in der obersten übergeordneten Datei pom.xml im Abschnitt pluginManagement hinzufügen.

Siehe this für weitere Details.

Klasse: org.Apache.maven.plugin.Assembly.io.DefaultAssemblyReader

Beispiel:

        <!-- Use the Assembly plugin to create a Zip file of all our dependencies. -->
        <plugin>
            <artifactId>maven-Assembly-plugin</artifactId>
            <version>2.2.1</version>
            <executions>
                <execution>
                    <id>make-Assembly</id>
                    <phase>package</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                    <configuration>
                        <descriptorId>Assembly-Zip-for-wid</descriptorId>
                    </configuration>
                </execution>
            </executions>
            <dependencies>
                <dependency>
                    <groupId>cz.ness.ct.ip.assemblies</groupId>
                    <artifactId>TEST_SharedAssemblyDescriptor</artifactId>
                    <version>1.0.0-SNAPSHOT</version>
                </dependency>
            </dependencies>
        </plugin>

Ich werde die Frage nicht direkt beantworten, da andere dies bereits getan haben, aber ich frage mich wirklich, ob es eine gute Idee ist, alle Abhängigkeiten in das Glas des Projekts selbst einzubetten.

Ich verstehe den Punkt (einfache Bereitstellung/Verwendung), aber es hängt vom Anwendungsfall Ihres Projekts ab (und es kann Alternativen geben (siehe unten)).

Wenn Sie es vollständig eigenständig verwenden, warum nicht?.

Wenn Sie Ihr Projekt jedoch in anderen Kontexten verwenden (z. B. in einer Webanwendung oder in einem Ordner, in dem sich andere Jars befinden), befinden sich möglicherweise JAR-Duplikate in Ihrem Klassenpfad (die im Ordner, die in den Jars). Vielleicht kein Angebot, aber ich vermeide dies normalerweise.

Eine gute Alternative:

  • stellen Sie Ihre Anwendung als ZIP/WAR-Datei bereit: Das Archiv enthält die JAR-Datei Ihres Projekts und alle abhängigen JAR-Dateien.
  • verwenden Sie einen dynamischen Klassenlade-Mechanismus (siehe Spring, oder Sie können dies ganz einfach selbst tun), um einen einzelnen Einstiegspunkt für Ihr Projekt zu haben (eine einzelne Klasse zum Starten - siehe Manifest-Mechanismus in einer anderen Antwort), der (dynamisch) zu dem hinzukommt aktuelle Klassenpfad alle anderen benötigten Gläser.

So können Sie Ihr Projekt am Ende mit einem Manifest und einem "speziellen dynamischen Klassenladeprogramm" starten mit:

Java -jar ProjectMainJar.jar com.stackoverflow.projectName.MainDynamicClassLoaderClass
5
SRG

Um dieses Problem zu beheben, verwenden wir das Maven Assembly Plugin, das die JAR zusammen mit ihren abhängigen JARs in einer einzigen ausführbaren JAR-Datei erstellt. Fügen Sie einfach die unten stehende Plugin-Konfiguration in Ihre pom.xml-Datei ein.

<build>
   <pluginManagement>
      <plugins>
         <plugin>
            <groupId>org.Apache.maven.plugins</groupId>
            <artifactId>maven-Assembly-plugin</artifactId>
            <configuration>
               <archive>
                  <manifest>
                     <addClasspath>true</addClasspath>
                     <mainClass>com.your.package.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>
   </pluginManagement>
</build>

Vergessen Sie danach nicht, das MAVEN-Tool mit diesem Befehl auszuführen: mvn clean compile Assembly: single

http://jkoder.com/maven-creating-a-jar-together-with-its-dependency-jars-into-a-single-executable-jar-file/

4
Anoop Rai

Um eine ausführbare JAR-Datei über die Befehlszeile selbst zu erstellen, führen Sie einfach den folgenden Befehl im Projektpfad aus:

mvn Assembly:assembly
3
Mayank

Ich habe die in diesem Beitrag erwähnten Tree Plugins verglichen. Ich habe 2 Gläser und ein Verzeichnis mit allen Gläsern erstellt. Ich habe die Ergebnisse verglichen und definitiv ist das Maven-Shadow-Plugin das Beste. Meine Herausforderung bestand darin, dass ich mehrere Quellressourcen, die zusammengeführt werden mussten, sowie Jax-Rs und JDBC-Services habe. Sie alle wurden vom Shade-Plugin im Vergleich zum Maven-Assembly-Plugin korrekt eingebunden. In diesem Fall schlägt der Spring fehl, es sei denn, Sie kopieren sie in Ihren eigenen Ressourcenordner und führen sie einmal manuell zusammen. Beide Plugins geben den richtigen Abhängigkeitsbaum aus. Ich hatte mehrere Gültigkeitsbereiche wie testen, bereitstellen, kompilieren usw. Der Test und die bereitgestellten wurden von beiden Plugins übersprungen. Sie haben beide das gleiche Manifest produziert, aber ich konnte Lizenzen mit dem Schatten-Plugin unter Verwendung ihres Transformators konsolidieren. Mit dem Maven-Dependency-Plugin haben Sie diese Probleme natürlich nicht, da die Gläser nicht extrahiert werden. Aber wie einige andere gezeigt haben, müssen Sie eine zusätzliche Datei (en) tragen, um richtig zu arbeiten. Hier ist ein Ausschnitt aus der pom.xml

            <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>
                        <includeScope>compile</includeScope>
                        <excludeTransitive>true</excludeTransitive>
                        <overWriteReleases>false</overWriteReleases>
                        <overWriteSnapshots>false</overWriteSnapshots>
                        <overWriteIfNewer>true</overWriteIfNewer>
                    </configuration>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <groupId>org.Apache.maven.plugins</groupId>
            <artifactId>maven-Assembly-plugin</artifactId>
            <version>2.6</version>
            <configuration>
                <archive>
                    <manifest>
                        <addClasspath>true</addClasspath>
                        <mainClass>com.rbccm.itf.cdd.poller.landingzone.LandingZonePoller</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>
        <plugin>
            <groupId>org.Apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <version>2.4.3</version>
            <configuration>
                <shadedArtifactAttached>false</shadedArtifactAttached>
                <keepDependenciesWithProvidedScope>false</keepDependenciesWithProvidedScope>
                <transformers>
                    <transformer implementation="org.Apache.maven.plugins.shade.resource.AppendingTransformer">
                        <resource>META-INF/services/javax.ws.rs.ext.Providers</resource>
                    </transformer>
                    <transformer implementation="org.Apache.maven.plugins.shade.resource.AppendingTransformer">
                        <resource>META-INF/spring.factories</resource>
                    </transformer>
                    <transformer implementation="org.Apache.maven.plugins.shade.resource.AppendingTransformer">
                        <resource>META-INF/spring.handlers</resource>
                    </transformer>
                    <transformer implementation="org.Apache.maven.plugins.shade.resource.AppendingTransformer">
                        <resource>META-INF/spring.schemas</resource>
                    </transformer>
                    <transformer implementation="org.Apache.maven.plugins.shade.resource.AppendingTransformer">
                        <resource>META-INF/spring.tooling</resource>
                    </transformer>
                    <transformer implementation="org.Apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
                    <transformer implementation="org.Apache.maven.plugins.shade.resource.ManifestResourceTransformer"/>
                    <transformer implementation="org.Apache.maven.plugins.shade.resource.ApacheLicenseResourceTransformer">
                    </transformer>
                </transformers>
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>shade</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
3
Fabio

Das ist der beste Weg, den ich gefunden habe:

  <plugin>
    <groupId>org.Apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>2.4</version>
    <configuration>
      <archive>
        <manifest>
        <addClasspath>true</addClasspath>
        <mainClass>com.myDomain.etc.MainClassName</mainClass>
        <classpathPrefix>dependency-jars/</classpathPrefix>
        </manifest>
      </archive>
    </configuration>
  </plugin>
  <plugin>
    <groupId>org.Apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <version>2.5.1</version>
    <executions>
      <execution>
        <id>copy-dependencies</id>
        <phase>package</phase>
        <goals>
            <goal>copy-dependencies</goal>
        </goals>
        <configuration>
            <outputDirectory>
               ${project.build.directory}/dependency-jars/
            </outputDirectory>
        </configuration>
      </execution>
    </executions>
  </plugin>

Bei dieser Konfiguration befinden sich alle Abhängigkeiten in /dependency-jars. Meine Anwendung hat keine Klasse Main, sondern nur Kontextklassen, aber eine meiner Abhängigkeiten hat eine Klasse Main (com.myDomain.etc.MainClassName), die den JMX-Server startet und eine start empfängt. oder ein stop Parameter. Damit konnte ich meine Anwendung wie folgt starten:

Java -jar ./lib/TestApp-1.0-SNAPSHOT.jar start

Ich warte, es ist nützlich für euch alle.

2
EliuX

Etwas, das für mich funktioniert hat, war:

  <plugin>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
      <execution>
        <id>unpack-dependencies</id>
        <phase>prepare-package</phase>
        <goals>
          <goal>unpack-dependencies</goal>
        </goals>
        <configuration>
          <outputDirectory>${project.build.directory}/classes</outputDirectory>
        </configuration>
      </execution>

    </executions>
  </plugin>


  <plugin>
    <groupId>org.Apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <executions>
      <execution>
        <id>unpack-dependencies</id>
        <phase>package</phase>
      </execution>
    </executions>
    <configuration>
      <archive>
        <manifest>
          <addClasspath>true</addClasspath>
          <classpathPrefix>lib/</classpathPrefix>
          <mainClass>SimpleKeyLogger</mainClass>
        </manifest>
      </archive>
    </configuration>
  </plugin>

Ich hatte außergewöhnlichen Fall, weil meine Abhängigkeit System eins war:

<dependency>
  ..
  <scope>system</scope>
  <systemPath>${project.basedir}/lib/myjar.jar</systemPath>
</dependency>

Ich habe den von @ user189057 bereitgestellten Code mit Änderungen geändert: 1) Das maven-dependency-plugin wird in der Phase "prepare-package" ausgeführt. 2) Ich extrahiere die entpackte Klasse direkt in "target/classes".

2
fascynacja

Sie können dieses Plug-in auch verwenden, es ist ziemlich gut und ich verwende es zum Verpacken meiner Gläser http://sonatype.github.io/jarjar-maven-plugin/

2
Adelin

Hinzufügen zu pom.xml:

  <dependency>
            <groupId>com.jolira</groupId>
            <artifactId>onejar-maven-plugin</artifactId>
            <version>1.4.4</version>
  </dependency>

und

<plugin>
       <groupId>com.jolira</groupId>
       <artifactId>onejar-maven-plugin</artifactId>
       <version>1.4.4</version>
       <executions>
              <execution>
                     <goals>
                         <goal>one-jar</goal>
                     </goals>
              </execution>
       </executions>
</plugin>

Das ist es. Das nächste mvn-Paket erstellt zusätzlich ein Fettglas, einschließlich aller Abhängigkeitsgläser.

2
Aydin K.

Es gibt bereits Millionen von Antworten. Ich wollte hinzufügen, dass Sie <mainClass> nicht benötigen, wenn Sie Ihrer Anwendung kein entryPoint hinzufügen müssen. APIs müssen beispielsweise nicht unbedingt die Methode main haben.

maven plugin config

  <build>
    <finalName>log-enrichment</finalName>
    <plugins>
      <plugin>
        <artifactId>maven-Assembly-plugin</artifactId>
        <configuration>
          <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
          </descriptorRefs>
        </configuration>
      </plugin>
    </plugins>
  </build>

bauen

mvn clean compile Assembly:single

überprüfen

ll target/
total 35100
drwxrwx--- 1 root vboxsf     4096 Sep 29 16:25 ./
drwxrwx--- 1 root vboxsf     4096 Sep 29 16:25 ../
drwxrwx--- 1 root vboxsf        0 Sep 29 16:08 archive-tmp/
drwxrwx--- 1 root vboxsf        0 Sep 29 16:25 classes/
drwxrwx--- 1 root vboxsf        0 Sep 29 16:25 generated-sources/
drwxrwx--- 1 root vboxsf        0 Sep 29 16:25 generated-test-sources/
-rwxrwx--- 1 root vboxsf 35929841 Sep 29 16:10 log-enrichment-jar-with-dependencies.jar*
drwxrwx--- 1 root vboxsf        0 Sep 29 16:08 maven-status/
2
prayagupd

Ich habe hier die am häufigsten gewählte Antwort ausprobiert und es geschafft, das Glas zum Laufen zu bringen. Aber das Programm lief nicht richtig. Ich weiß nicht, was der Grund war. Wenn ich versuche, von Eclipse aus zu starten, erhalte ich ein anderes Ergebnis, aber wenn ich das jar über die Befehlszeile starte, erhalte ich ein anderes Ergebnis (es stürzt mit einem programmspezifischen Laufzeitfehler ab).

Ich hatte eine ähnliche Anforderung wie das OP, nur dass ich zu viele (Maven) Abhängigkeiten für mein Projekt hatte. Zum Glück funktionierte für mich nur die Verwendung von Eclipse. Sehr einfach und sehr unkompliziert. Dies ist keine Lösung für das OP, sondern eine Lösung für jemanden, der ähnliche Anforderungen hat, aber viele Maven-Abhängigkeiten hat.

1) Klicken Sie einfach mit der rechten Maustaste auf Ihren Projektordner (in Eclipse) und wählen Sie Export

2) Wählen Sie dann Java -> Runnable Jar

3) Sie werden aufgefordert, den Speicherort der JAR-Datei zu wählen

4) Wählen Sie abschließend die Klasse mit der Main-Methode aus, die Sie ausführen möchten, und wählen Sie Package dependencies with the Jar file und klicken Sie auf Finish.

2
Rocky Inde

Für alle, die nach Optionen suchen, um bestimmte Abhängigkeiten aus dem uber-jar auszuschließen, ist dies eine Lösung, die für mich funktioniert hat:

<project...>
<dependencies>
        <dependency>
            <groupId>org.Apache.spark</groupId>
            <artifactId>spark-core_2.11</artifactId>
            <version>1.6.1</version>
            <scope>provided</scope> <=============
        </dependency>
</dependencies>
<build>
        <plugins>
            <plugin>
                <artifactId>maven-Assembly-plugin</artifactId>
                <configuration>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                    <archive>
                        <manifest>
                            <mainClass>...</mainClass>
                        </manifest>
                    </archive>
                </configuration>
                <executions>
                    <execution>
                        <id>make-Assembly</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

Es ist also keine Konfiguration des mvn-Assembly-Plugins, sondern eine Eigenschaft der Abhängigkeit.

2
Paul Bormans

Dies kann auch eine Option sein. Sie können Ihre JAR-Datei erstellen

<build>
    <plugins>
        <plugin>
            <!-- Build an executable JAR -->
            <groupId>org.Apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>2.4</version>
            <configuration>
                <archive>
                    <manifest>
                        <addClasspath>true</addClasspath>
                        <classpathPrefix>lib/</classpathPrefix>
                        <mainClass>WordListDriver</mainClass>
                    </manifest>
                </archive>
            </configuration>
        </plugin>
    </plugins>
</build>
2
salmanbw

Das Maven-Assembly-Plugin hat bei mir sehr gut funktioniert. Ich habe Stunden mit dem Maven-Dependency-Plugin verbracht und konnte es nicht zum Laufen bringen. Der Hauptgrund war, dass ich im Konfigurationsabschnitt explizit die Artefaktelemente definieren musste, die enthalten sein sollten, wie es in der Dokumentation beschrieben ist. Es gibt ein Beispiel für die Fälle, in denen Sie es wie folgt verwenden möchten: mvn dependency:copy, in denen keine Artefaktelemente enthalten sind, es jedoch nicht funktioniert.

1
Chris

Dieser Blog-Beitrag zeigt einen anderen Ansatz mit der Kombination der Plugins maven-jar und maven-Assembly. Mit der Assembly-Konfigurations-XML aus dem Blog-Beitrag kann auch gesteuert werden, ob Abhängigkeiten erweitert oder nur in einem Ordner gesammelt und von einem Klassenpfadeintrag im Manifest referenziert werden:

Die ideale Lösung besteht darin, die JAR-Dateien in einen lib-Ordner aufzunehmen, und die manifest.mf-Datei der Haupt-JAR-Datei enthält alle JAR-Dateien in classpath.

Und genau das wird hier beschrieben: https://caffebig.wordpress.com/2013/04/05/executable-jar-file-with-dependent-jars-using-maven/

1
Jan Ziegler
<build>
    <plugins>
        <plugin>
            <groupId>org.Apache.maven.plugins</groupId>
            <artifactId>maven-Assembly-plugin</artifactId>
            <version>2.4.1</version>
            <configuration>
                <!-- get all project dependencies -->
                <descriptorRefs>
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
            </configuration>
            <executions>
                <execution>
                    <id>make-Assembly</id>
                    <!-- bind to the packaging phase -->
                    <phase>package</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>
0
Shang Gao