Ich möchte mein Projekt zur Verteilung in eine einzige ausführbare JAR packen.
Wie kann ich aus einem Maven-Projektpaket alle Abhängigkeits-JARs in meine Ausgabe-JAR erstellen?
Ich möchte mein Projekt zur Verteilung in eine einzige ausführbare JAR packen.
Wie kann ich aus einem Maven-Projektpaket alle Abhängigkeits-JARs in meine Ausgabe-JAR erstellen?
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
Das Kompilierungsziel sollte vor dem Zusammenbau hinzugefügt werden: einzeln oder anderweitig ist der Code in Ihrem eigenen 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. Dadurch wird sichergestellt, dass die JAR beim Ausführen mvn install
oder Ausführen einer Bereitstellung / Version erstellt 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>
mvn clean compile assembly:single
.
<appendAssemblyId>false</appendAssemblyId>
in das hinzufügen configuration
, um das nervige Suffix "-jar-with-dependencies" im Namen zu vermeiden
compile
und du bist geschraubt.
Sie können das Abhängigkeits-Plugin verwenden, um alle Abhängigkeiten vor der Paketphase in einem separaten Verzeichnis zu generieren und diese 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 es ${project.build.directory}/classes/lib
als OutputDirectory verwenden, um alle JAR-Dateien in das Haupt-JAR zu integrieren. Anschließend müssen Sie jedoch benutzerdefinierten Klassenladecode hinzufügen, um die Jars zu laden.
${project.build.directory}/classes/lib
als outputDirectory
ein Haupt .jar mit allen Abhängigkeiten innerhalb haben, aber - wie benutzerdefinierten Classloading Code hinzufügen diese Gläser zu laden? Ich muss die Arbeit wie folgt ausführen : java -jar main-jar-with-deps.jar
. Ist das möglich ?
Ich habe über verschiedene Möglichkeiten gebloggt, dies zu tun.
Siehe Ausführbares Glas mit Apache Maven (WordPress)
oder ausführbares-jar-with-maven-Beispiel (GitHub)
Diese Vor- und Nachteile werden von Stephan bereitgestellt .
<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>
<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 jar
ist das tatsächlich mit externen Klassenpfadelementen ausführbar.
$ java -jar target/${project.build.finalName}.jar
Die jar
Datei kann nur mit dem Geschwisterverzeichnis ausgeführt werden ...lib/
. 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)
welche jeweils das jar
und enthält lib/*
.
<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
.
<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
.
<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>
<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
.
Wenn wir die Antwort von Unanswered nehmen und neu formatieren, 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 Teil Ihres Builds zu machen, anstatt es explizit aufzurufen. 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 das package
Lebenszyklusereignis. Ein Problem ist jedoch, dass Sie das assembly:single
Ziel aufrufen müssen, wenn Sie es 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>
Verwenden Sie das Maven-Shade-Plugin, um alle Abhängigkeiten in ein 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 Ressourcendateien in den Jars denselben Namen haben und das Plugin versucht, alle Ressourcendateien zu verpacken
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>
Ich habe lange das Maven Assembly Plugin verwendet , aber ich konnte keine Lösung für das Problem mit finden "already added, skipping"
. Jetzt benutze 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 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>
Sie können das Maven-Dependency-Plugin verwenden, aber die Frage war, wie Sie eine ausführbare JAR erstellen. Um dies zu erreichen, muss die Antwort von Matthew Franglen wie folgt geändert werden (übrigens dauert die Erstellung 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>
Sie können das Maven-Shade-Plugin verwenden, um ein Uber-Glas 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>
Eine weitere Option, wenn Sie die anderen JAR-Inhalte in Ihrer einzelnen resultierenden JAR wirklich neu verpacken möchten, ist das Maven Assembly-Plugin . Es entpackt und packt dann alles in ein Verzeichnis über <unpack>true</unpack>
. Dann hätten Sie einen zweiten Durchgang, der es zu einem massiven JAR machte.
Eine weitere Option ist das OneJar-Plugin . Dies führt die obigen Umpackaktionen in einem Schritt aus.
Sie können Ihrer 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 müssen Sie über die Konsole in das Verzeichnis wechseln, in dem sich die Datei 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, wenn Sie mit cd ./target in das Ausgabeverzeichnis (Zielverzeichnis) wechseln und Ihr jar mit einem Befehl starten , der java -jar mavenproject1-1.0-SNAPSHOT-jar-with-dependencies.jar ähnelt .
Ich habe dies mit Apache Maven 3.0.3 getestet .
Ich habe jede dieser Antworten durchgesehen, um ein fettes ausführbares Glas zu erstellen, das alle Abhängigkeiten enthält, und keine davon hat richtig funktioniert. 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.
plugin
Element geht pom.xml
unter build/plugins
.
Sie könnten das maven-shade-plugin
und kombinieren maven-jar-plugin
.
maven-shade-plugin
packt Ihre Klassen und alle Abhängigkeiten in eine einzige JAR-Datei.maven-jar-plugin
die Hauptklasse Ihres ausführbaren jar angeben (siehe Set Up The Classpath , Kapitel "Make The Jar Executable").Beispiel für eine 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
Ken Liu hat es meiner Meinung nach richtig. 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 Hauptartefakt 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>
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 sich in der Phase "Ressourcen generieren" befinden, da es in der Paketphase nicht als Ressourcen enthalten ist. Versuchen Sie es mit einem sauberen Paket und Sie werden sehen.
Problem beim Auffinden der freigegebenen Assembly-Datei mit dem Maven-Assembly-Plugin-2.2.1?
Versuchen Sie, den Konfigurationsparameter deskriptors ID anstelle der Parameter deskriptoren / deskriptor oder deskriptorsRefs / deskriptors zu verwenden.
Keiner von beiden tut das, was Sie brauchen: Suchen Sie im Klassenpfad nach der Datei. Natürlich müssen Sie das Paket hinzufügen, in dem sich die gemeinsam genutzte Assembly im Klassenpfad des Maven-Assembly-Plugins 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.
Sehen Sie dies 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>
Um dieses Problem zu beheben, verwenden wir das Maven Assembly Plugin, das die JAR zusammen mit ihren Abhängigkeits-JARs in einer einzigen ausführbaren JAR-Datei erstellt. Fügen Sie einfach die folgende 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 dem Befehl mvn clean compile Assembly: single auszuführen
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 Projektglas selbst einzubetten.
Ich sehe 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:
So können Sie mit nur einem Manifest und einem "speziellen dynamischen Klassenladeprogramm" Ihr Projekt starten mit:
java -jar ProjectMainJar.jar com.stackoverflow.projectName.MainDynamicClassLoaderClass
Um eine ausführbare JAR über die Befehlszeile selbst zu erstellen, führen Sie einfach den folgenden Befehl über den Projektpfad aus:
mvn assembly:assembly
pom.xml
sonst bekommst du Error reading assemblies: No assembly descriptors found.
. Das passiert mir sowieso.
Dies 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 Main
Klasse, nur Kontext-Klassen, aber eine meiner Abhängigkeiten hat eine Main
Klasse ( com.myDomain.etc.MainClassName
), die den JMX-Server startet und eine empfängtstart
oder einen stop
Parameter . Damit konnte ich meine Bewerbung folgendermaßen starten:
java -jar ./lib/TestApp-1.0-SNAPSHOT.jar start
Ich warte, es ist nützlich für euch alle.
Ich habe die in diesem Beitrag erwähnten Baum-Plugins verglichen. Ich habe 2 Gläser und ein Verzeichnis mit allen Gläsern generiert. Ich habe die Ergebnisse verglichen und definitiv ist das Maven-Shade-Plugin das Beste. Meine Herausforderung bestand darin, dass ich über mehrere Spring-Ressourcen verfügte, die zusammengeführt werden mussten, sowie über Jax-Rs und JDBC-Services. Sie wurden alle vom Schatten-Plugin im Vergleich zum Maven-Assembly-Plugin richtig zusammengeführt. In diesem Fall schlägt die Feder 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 Bereiche wie testen, bereitstellen, kompilieren usw. Der Test und die bereitgestellten wurden von beiden Plugins übersprungen. Beide haben das gleiche Manifest erstellt, aber ich konnte Lizenzen mit dem Shadow-Plugin mithilfe ihres Transformators konsolidieren. Mit dem Maven-Dependency-Plugin natürlich nicht ' Ich habe diese Probleme nicht, weil die Gläser nicht extrahiert werden. Aber wie einige andere darauf hingewiesen haben, müssen Sie eine zusätzliche Datei (en) mit sich führen, um ordnungsgemäß zu funktionieren. 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>
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 einen 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 folgenden Änderungen geändert: 1) Das Maven-Dependency-Plugin wird in der Phase "Prepare-Package" ausgeführt. 2) Ich extrahiere die entpackte Klasse direkt in "Ziel / Klassen".
Ich habe hier die am besten gewählte Antwort versucht und konnte das Glas zum Laufen bringen. Das Programm lief jedoch nicht richtig. Ich weiß nicht, was der Grund war. Wenn ich versuche wegzulaufenEclipse
, erhalte ich ein anderes Ergebnis, aber wenn ich das JAR über die Befehlszeile , 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. Glücklicherweise war die einzige Lösung, die für mich funktionierte, die Verwendung Eclipse
. Sehr einfach und sehr unkompliziert. Dies ist keine Lösung für das OP, sondern eine Lösung für jemanden, der eine ähnliche Anforderung 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 auszuwählen
4) Wählen Sie abschließend die Klasse mit der Hauptmethode aus, die Sie ausführen möchten, und wählen Sie sie aus Package dependencies with the Jar file
und klicken Sie daraufFinish
Dies könnte 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>
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 handelt sich also nicht um eine Konfiguration des MVN-Assembly-Plugins, sondern um eine Eigenschaft der Abhängigkeit.
Es gibt bereits Millionen von Antworten. Ich wollte hinzufügen, dass Sie nicht benötigen, <mainClass>
wenn Sie Ihrer Anwendung keinen entryPoint hinzufügen müssen. Beispielsweise müssen APIs nicht unbedingt über eine main
Methode verfügen .
<build>
<finalName>log-enrichment</finalName>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
</plugins>
</build>
mvn clean compile assembly:single
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/
Zur pom.xml hinzufügen:
<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.
Das Maven-Assembly-Plugin hat bei mir super 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 dort ein Beispiel für die Fälle, in denen Sie es verwenden möchten, wie:, mvn dependency:copy
in denen keine Artefaktelemente enthalten sind, es aber nicht funktioniert.
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 durch einen Klassenpfadeintrag im Manifest referenziert werden:
Die ideale Lösung besteht darin, die Jars in einen lib-Ordner aufzunehmen, und die manifest.mf-Datei des Hauptglases enthält alle Jars im Klassenpfad.
Und genau das wird hier beschrieben: https://caffebig.wordpress.com/2013/04/05/executable-jar-file-with-dependent-jars-using-maven/
<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>
Okay, das ist meine Lösung. Ich weiß, dass die Datei pom.xml nicht verwendet wird. Ich hatte jedoch das Problem, dass mein Programm auf Netbeans kompiliert und ausgeführt wurde, aber es schlug fehl, als ich Java -jar MyJarFile.jar ausprobierte. Jetzt verstehe ich Maven nicht ganz und ich denke, aus diesem Grund hatte Netbeans 8.0.2 Probleme, meine JAR-Datei in eine Bibliothek aufzunehmen, um sie in eine JAR-Datei zu kopieren. Ich habe darüber nachgedacht, wie ich in Eclipse JAR-Dateien ohne Maven verwendet habe.
Es ist Maven, der alle Abhängigkeiten und Plugins kompilieren kann. Nicht Netbeans. (Wenn Sie Netbeans erhalten und Java .jar verwenden können, sagen Sie mir bitte, wie (^. ^) V)
[Gelöst - für Linux] durch Öffnen eines Terminals.
Dann
cd /MyRootDirectoryForMyProject
Nächster
mvn org.apache.maven.plugins:maven-compiler-plugin:compile
Nächster
mvn install
Dadurch wird eine JAR-Datei im Zielverzeichnis erstellt.
MyJarFile-1.0-jar-with-dependencies.jar
Jetzt
cd target
(Möglicherweise müssen Sie Folgendes ausführen: chmod +x MyJarFile-1.0-jar-with-dependencies.jar
)
Und schlussendlich
java -jar MyJarFile-1.0-jar-with-dependencies.jar
Bitte sehen Sie
https://cwiki.apache.org/confluence/display/MAVEN/LifecyclePhaseNotFoundException
Ich werde diese Lösung auf einigen anderen Seiten mit einem ähnlichen Problem veröffentlichen. Hoffentlich kann ich jemanden vor einer Woche der Frustration retten.