2891 Stimmen

Wie kann ich mit Maven ein ausführbares JAR mit Abhängigkeiten erstellen?

Ich möchte mein Projekt in ein einziges ausführbares JAR-Paket verpacken, um es zu verteilen.

Wie kann ich ein Maven-Projekt dazu bringen, alle abhängigen JARs in mein Ausgabe-JAR zu packen?

15 Stimmen

Bitte erklären Sie, auf welches Ziel des Abhängigkeits-Plugins Sie sich beziehen. Ich kenne kein Ziel, das das tut, was die ursprüngliche Frage verlangt: alle Abhängigkeiten entweder A) in das Autoren-Jar durch Umpacken zu packen, oder B) ein ausführbares Jar zu erstellen, das die anderen in einem Klassenpfad von MANIFEST.MF hat

2 Stimmen

Dies könnte für Sie nützlich sein rationaljava.com/2015/02/

9voto

Problem mit dem Auffinden der gemeinsamen Assembly-Datei mit maven-assembly-plugin-2.2.1?

Versuchen Sie, den Konfigurationsparameter descriptorId anstelle der Parameter descriptors/descriptor oder descriptorRefs/descriptorRef zu verwenden.

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

Siehe este für weitere Einzelheiten.

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>

7voto

Paul Bormans Punkte 1202

Für alle, die nach Optionen suchen, um bestimmte Abhängigkeiten aus dem uber-jar auszuschließen, ist dies eine Lösung, die bei mir 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 handelt sich also nicht um eine Konfiguration des mvn-assembly-plugin, sondern um eine Eigenschaft der Abhängigkeit.

0 Stimmen

Meinen Sie, dass maven-assembly-plugin den für die Abhängigkeit angegebenen Bereich beachtet und standardmäßig NUR Laufzeitabhängigkeiten einschließt? Und löst es auch transitiv für die transitiven Abhängigkeiten auf?

7voto

Fabio Punkte 503

Ich habe die in diesem Beitrag erwähnten Baum-Plugins verglichen. Ich habe 2 Jars und ein Verzeichnis mit allen Jars erstellt. Ich habe die Ergebnisse verglichen und das maven-shade-plugin ist definitiv das beste. Meine Herausforderung war, dass ich mehrere Spring-Ressourcen habe, die zusammengeführt werden mussten, sowie jax-rs und JDBC-Dienste. Im Vergleich zum maven-assembly-plugin wurden sie alle vom shade-plugin korrekt zusammengeführt. In diesem Fall wird Spring fehlschlagen, es sei denn, Sie kopieren sie in Ihren eigenen Ressourcenordner und führen sie einmal manuell zusammen. Beide Plugins geben den korrekten Abhängigkeitsbaum aus. Ich hatte mehrere Scopes wie test, provide, compile, etc. test und provided wurden von beiden Plugins übersprungen. Beide produzierten das gleiche Manifest, aber ich konnte die Lizenzen mit dem Shade-Plugin konsolidieren, indem ich ihren Transformer verwendete. Mit dem maven-dependency-plugin hat man diese Probleme natürlich nicht, da die jars nicht extrahiert werden. Aber wie schon einige andere gesagt haben, muss man eine zusätzliche Datei mitnehmen, damit es richtig funktioniert. 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>

6voto

SRG Punkte 1551

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

Ich verstehe den Punkt (einfache Bereitstellung/Nutzung), aber es hängt vom Anwendungsfall Ihres Projekts ab (und es gibt möglicherweise Alternativen (siehe unten)).

Wenn Sie es völlig eigenständig verwenden, warum nicht.

Aber wenn Sie Ihr Projekt in anderen Kontexten verwenden (z. B. in einer Webapp oder in einem Ordner, in dem sich andere Jars befinden), haben Sie möglicherweise Jar-Duplikate in Ihrem Klassenpfad (die im Ordner, die in den Jars). Vielleicht nicht ein Gebot Deal, aber ich in der Regel vermeiden dies.

Eine gute Alternative:

  • Stellen Sie Ihre Anwendung als .zip / .war bereit: Das Archiv enthält die Jar-Datei Ihres Projekts und alle abhängigen Jar-Dateien;
  • Verwenden Sie einen dynamischen Classloader-Mechanismus (siehe Spring, oder Sie können dies leicht selbst tun), um einen einzigen Einstiegspunkt für Ihr Projekt zu haben (eine einzige Klasse zum Starten - siehe den Manifest-Mechanismus in einer anderen Antwort), der (dynamisch) dem aktuellen Klassenpfad alle anderen benötigten Jars hinzufügt.

Auf diese Weise, mit letztlich nur einem Manifest und einem "speziellen dynamischen Classloader main", können Sie Ihr Projekt mit :

java -jar ProjectMainJar.jar com.stackoverflow.projectName.MainDynamicClassLoaderClass

6voto

prayagupa Punkte 28548

Es gibt bereits Millionen von Antworten, ich wollte nur hinzufügen, dass Sie nicht brauchen <mainClass> wenn Sie entryPoint nicht zu Ihrer Anwendung hinzufügen müssen. Zum Beispiel müssen APIs nicht unbedingt über main Methode.

Maven-Plugin-Konfiguration

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

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/

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X