Mit Maven 2 ein lauffähiges Glas bauen

82

Ich bin relativ neu im Maven-Mantra, aber ich versuche, mit Maven ein ausführbares Kommandozeilen-Jar zu erstellen. Ich habe meine Abhängigkeiten eingerichtet, aber wenn ich mvn installdas Glas ausführe und versuche, es auszuführen, passieren zwei Dinge. Erstens wird keine Hauptklasse gefunden, was korrigierbar ist. Wenn ich dies korrigiert habe, erhalte ich beim Ausführen Fehler, die darauf hinweisen, dass Klassen nicht gefunden werden können.

Maven packt meine Abhängigkeitsbibliotheken nicht in das JAR, daher kann ich das JAR nicht als eigenständige Anwendung ausführen. Wie korrigiere ich das?

Stefan Kendall
quelle
Sie können IDE für Maven wie Netbenas
Sajad Bahmani
7
@SjB: und das löst das Problem auf magische Weise? Das glaube ich nicht.
Joachim Sauer
1
Genaues Duplikat von was genau?
Stefan Kendall
Vielleicht dieser eine stackoverflow.com/questions/1832853/… oder dieser eine stackoverflow.com/questions/574594/… (aber die akzeptierte Antwort ist falsch) oder dieser eine stackoverflow.com/questions/1814526/… . Eigentlich scheint dies eine der häufigsten Fragen zu Maven zu sein ...
Pascal Thivent
1
Die anderen Antworten sind nicht so sauber, und uber jar (ueber falsch geschrieben) erwähnt die Ausführbarkeit nicht. Darüber hinaus sind die anderen Themen mit irrelevantem Material übersät, wie z. B. Quellenebene usw.
Stefan Kendall

Antworten:

113

Der einfachste Weg, dies zu tun, besteht darin, eine Assembly mit dem maven-assembly-pluginund dem vordefinierten jar-with-dependenciesDeskriptor zu erstellen . Sie müssen auch ein Manifest mit einem Hauptklasseneintrag für dieses Überglas erstellen. Das folgende Snippet zeigt, wie Sie das Assembly-Plugin dafür konfigurieren:

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

Führen Sie zum Generieren der Assembly einfach Folgendes aus:

mvn assembly:assembly

Wenn Sie die Assembly als Teil Ihres Builds generieren möchten, binden Sie das assembly:singleMojo einfach an die Paketphase:

<build>
  <plugins>
    <plugin>
      <artifactId>maven-assembly-plugin</artifactId>
      <configuration>
        <descriptorRefs>
          <descriptorRef>jar-with-dependencies</descriptorRef>
        </descriptorRefs>
        <archive>
          <manifest>
            <mainClass>fully.qualified.MainClass</mainClass>
          </manifest>
        </archive>
      </configuration>
      <executions>
        <execution>
          <phase>package</phase>
          <goals>
            <goal>single</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>

Und einfach laufen lassen:

mvn package
Pascal Thivent
quelle
1
Das Maven-Shade-Plugin funktioniert ebenfalls ähnlich und ist diesem Zweck gewidmet.
Dominic Mitchell
4
Dies funktioniert nicht für Spring und andere Bibliotheken, die mehrere Ressourcen mit demselben Namen im Klassenpfad erwarten. Im Fall von spring ist META-INF \ spring.schemas in mehreren Jars (Beans, JDBC usw.) enthalten und wird zum Konfigurieren der XML-Namespace-Unterstützung für den XML-Parser verwendet. Wenn Sie 'jar-with-dependencies' versuchen, schlägt das Pasing von application-context.xml zur Laufzeit mit etwas wie "org.xml.sax.SAXParseException: cvc-elt.1: Die Deklaration des Elements 'bean' kann nicht gefunden werden" fehl.
David Roussel
@ David Maven löst keine Java "Einschränkung". Verpacken Sie Ihre Anwendung in diesem Fall einfach sauber (dh nicht in einem Überglas).
Pascal Thivent
Dies funktioniert mit der Spring-Konfiguration ohne Probleme. Meine Hauptklasse lädt alle anderen Klassen mit Classpath Application-Kontext und diese Lösung funktioniert perfekt.
Vsingh
2
Das assembly:assemblyZiel ist veraltet
Jared Beck
25

Maven packt Ihre Abhängigkeiten nicht in Ihre JAR-Datei, da Sie dies normalerweise nicht mit Java-Programmen tun.

Stattdessen liefern Sie die Abhängigkeiten zusammen mit Ihrer JAR - Datei und nennen sie in der Class-PathKopfzeile des Manifests .

Um diesen Weg zu gehen, müssen Sie die addClasspathEigenschaft ( hier dokumentiert ) für das aktivieren maven-jar-plugin.

Wenn Sie wirklich alle Ihre Abhängigkeiten in Ihre JAR-Datei aufnehmen möchten, können Sie das Maven Assembly-Plugin verwenden, um eine zu erstellen jar-with-dependencies.

Joachim Sauer
quelle
4
+1 Es fiel mir schwer, Informationen darüber zu finden, wie Java-Programme normalerweise erstellt und verteilt werden sollen, insbesondere mit Maven.
Ed Brannin
8

Das würde ich für kleine Projekte tun. Meistens willst du kein einziges großes Glas.

zu erstellen: mvn clean dependency: copy-dependencies package

auszuführen ( im Zielverzeichnis ): java -cp myjar.jar: ./ dependency / * com.something.MyClass

user2409824
quelle
Toll! Ich habe dies in meinem Makefile im selben Verzeichnis wie pom.xml gespeichert. build: \ n mvn .... (was du gesagt hast)
Roboprog
Vielen Dank. Nachdem ich mehr als 2 Stunden im Internet gesucht hatte, fand ich diese sehr nützliche Antwort ....
Shekhar
6

Ich stimme Joachim Sauer zu,

Anstatt jar-with-dependency zu verwenden, sollten Sie das jar-Plugin in Ihrer pom.xml folgendermaßen konfigurieren:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>2.4</version>
    <configuration>
        <archive>
            <index>true</index>
            <manifest>
                <addClasspath>true</addClasspath>
                <mainClass>[mainClassFullName]</mainClass>
            </manifest>
            <manifestEntries>
                <mode>development</mode>
                <url>${project.url}</url>
                <key>value</key>
            </manifestEntries>
        </archive>
    </configuration>
</plugin>

Verwenden Sie diese Assemblykonfiguration, um die JAR-Abhängigkeiten zu Ihrer Assembly hinzuzufügen:

<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
  <id>zip-with-jars</id>
  <formats>
    <format>zip</format>
  </formats>
  <includeBaseDirectory>false</includeBaseDirectory>
  <dependencySets>
    <dependencySets>
    <dependencySet>
    <outputDirectory>/</outputDirectory>
    <useProjectArtifact>true</useProjectArtifact>
    <unpack>false</unpack>
    <scope>runtime</scope>
    </dependencySet>
</dependencySets>
  </dependencySets>
</assembly>
Formixian
quelle
2

Fügen Sie einfach den folgenden Code in pom.xml ein und führen Sie ihn aus als: maven: install. Das JAR wird im Zielordner von Eclipse erstellt, der als "java -jar Hello.jar" verwendet werden kann. Stellen Sie jedoch sicher, dass der Name der Hauptklasse com.abc.HelloWorld.java lautet

<build>
<plugins>
<plugin>
<groupid>org.apache.maven.plugins</groupid>
<artifactid>maven-shade-plugin</artifactid>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<finalname>HelloW</finalname>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestentries>
<main-class>com.abc.HelloWorld.java</main-class>
<build-number>1</build-number>
</manifestentries>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>

</build>
Pfanne
quelle