Mit Maven ein ausführbares Glas erstellen?


122

Ich versuche, mit maven ein ausführbares JAR für ein kleines Heimprojekt namens "logmanager" zu generieren, genau wie folgt:

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

Ich habe das dort gezeigte Snippet zur Datei pom.xml hinzugefügt und mvn Assembly: Assembly ausgeführt. Es werden zwei JAR-Dateien in logmanager / target generiert: logmanager-0.1.0.jar und logmanager-0.1.0-jar-with-dependencies.jar. Ich erhalte eine Fehlermeldung, wenn ich auf das erste Glas doppelklicke:

Could not find the main class: com.gorkwobble.logmanager.LogManager. Program will exit.

Ein etwas anderer Fehler, wenn ich auf jar-with-dependencies.jar doppelklicke:

Failed to load Main-Class manifest attribute from: C:\EclipseProjects\logmanager\target\logmanager-0.1.0-jar-with-dependencies.jar

Ich habe den Pfad und den Klassennamen kopiert und eingefügt und die Rechtschreibung im POM überprüft. Meine Hauptklasse startet gut mit einer Eclipse-Startkonfiguration. Kann mir jemand helfen, herauszufinden, warum meine JAR-Datei nicht ausgeführt wird? Warum gibt es zunächst zwei Gläser? Lassen Sie mich wissen, wenn Sie weitere Informationen benötigen.

Hier ist die vollständige pom.xmlals Referenz:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.gorkwobble</groupId>
  <artifactId>logmanager</artifactId>
  <name>LogManager</name>
  <version>0.1.0</version>
  <description>Systematically renames specified log files on a scheduled basis. Designed to help manage MUSHClient logging and prevent long, continuous log files.</description>
  <build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>2.2</version>
            <!-- nothing here -->
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>2.2-beta-4</version>
            <configuration>
              <descriptorRefs>
                <descriptorRef>jar-with-dependencies</descriptorRef>
              </descriptorRefs>
              <archive>
                <manifest>
                  <mainClass>com.gorkwobble.logmanager.LogManager</mainClass>
                </manifest>
              </archive>
            </configuration>
            <executions>
              <execution>
                <phase>package</phase>
                <goals>
                  <goal>single</goal>
                </goals>
              </execution>
            </executions>
          </plugin>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
              <source>1.6</source>
              <target>1.6</target>
            </configuration>
          </plugin>
    </plugins>
  </build>
  <dependencies>
    <!-- commons-lang -->
    <dependency>
        <groupId>commons-lang</groupId>
        <artifactId>commons-lang</artifactId>
        <version>2.4</version>
    </dependency> 

    <!-- Quartz scheduler -->
    <dependency>
        <groupId>opensymphony</groupId>
        <artifactId>quartz</artifactId>
        <version>1.6.3</version>
    </dependency>
    <!-- Quartz 1.6.0 depends on commons collections -->
    <dependency>
      <groupId>commons-collections</groupId>
      <artifactId>commons-collections</artifactId>
      <version>3.1</version>
    </dependency>
    <!-- Quartz 1.6.0 depends on commons logging -->
    <dependency>
      <groupId>commons-logging</groupId>
      <artifactId>commons-logging</artifactId>
      <version>1.1</version>
    </dependency>
    <!-- Quartz 1.6.0 requires JTA in non J2EE environments -->
    <dependency>
      <groupId>javax.transaction</groupId>
      <artifactId>jta</artifactId>
      <version>1.1</version>
      <scope>runtime</scope>
    </dependency>

    <!-- junitx test assertions -->
    <dependency>
        <groupId>junit-addons</groupId>
        <artifactId>junit-addons</artifactId>
        <version>1.4</version>
        <scope>test</scope>
    </dependency>

    <!-- junit dependency; FIXME: make this a separate POM -->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.1</version>
    </dependency>

  </dependencies>
  <dependencyManagement>
  </dependencyManagement>
</project>

Antworten:


244

Eigentlich denke ich, dass die Antwort in der von Ihnen erwähnten Frage einfach falsch ist ( UPDATE - 20101106: Jemand hat sie behoben, diese Antwort bezieht sich auf die Version vor der Bearbeitung ) und dies erklärt zumindest teilweise, warum Sie auf Probleme stoßen.


Es werden zwei JAR-Dateien in logmanager / target generiert: logmanager-0.1.0.jar und logmanager-0.1.0-jar-with-dependencies.jar.

Die erste ist die JAR des Logmanager-Moduls, das während der packagePhase von generiert wurde jar:jar(da das Modul eine Verpackung vom Typ hat jar). Die zweite ist die Assembly, die von assembly:assemblyden Klassen des aktuellen Moduls und seinen Abhängigkeiten generiert wurde und diese enthalten sollte (wenn Sie den Deskriptor verwendet haben jar-with-dependencies).

Ich erhalte eine Fehlermeldung, wenn ich auf das erste Glas doppelklicke:

Could not find the main class: com.gorkwobble.logmanager.LogManager. Program will exit.

Wenn Sie die vorgeschlagene Konfiguration des als Referenz veröffentlichten Links angewendet haben, haben Sie das JAR-Plugin so konfiguriert, dass ein ausführbares Artefakt erzeugt wird, etwa wie folgt:

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <configuration>
      <archive>
        <manifest>
          <addClasspath>true</addClasspath>
          <mainClass>com.gorkwobble.logmanager.LogManager</mainClass>
        </manifest>
      </archive>
    </configuration>
  </plugin>

Ist logmanager-0.1.0.jaralso in der Tat ausführbar, aber 1. das ist nicht das, was Sie wollen (weil es nicht alle Abhängigkeiten hat) und 2. es enthält nicht com.gorkwobble.logmanager.LogManager(das ist, was der Fehler sagt, überprüfen Sie den Inhalt des JAR).

Ein etwas anderer Fehler, wenn ich auf jar-with-dependencies.jar doppelklicke:

Failed to load Main-Class manifest attribute from: C:\EclipseProjects\logmanager\target\logmanager-0.1.0-jar-with-dependencies.jar

Wenn Sie das Assembly-Plugin wie vorgeschlagen konfiguriert haben, haben Sie Folgendes:

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-assembly-plugin</artifactId>
    <configuration>
      <descriptorRefs>
        <descriptorRef>jar-with-dependencies</descriptorRef>
      </descriptorRefs>
    </configuration>
  </plugin>

Mit dieser Einrichtung logmanager-0.1.0-jar-with-dependencies.jarenthält die Klassen aus dem aktuellen Modul und ihre Abhängigkeiten aber nach dem Fehler, das META-INF/MANIFEST.MF nicht einen enthält Main-ClassEintrag (das wahrscheinlich nicht das gleiche , wie in MANIFEST.MF LogManager-0.1.0.jar). Das Glas ist eigentlich nicht ausführbar, was wiederum nicht das ist, was Sie wollen.


Mein Vorschlag wäre also, das configurationElement aus dem Maven-Jar-Plugin zu entfernen und das Maven-Assembly-Plugin folgendermaßen zu konfigurieren:

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>2.2</version>
    <!-- nothing here -->
  </plugin>
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-assembly-plugin</artifactId>
    <version>2.2-beta-4</version>
    <configuration>
      <descriptorRefs>
        <descriptorRef>jar-with-dependencies</descriptorRef>
      </descriptorRefs>
      <archive>
        <manifest>
          <mainClass>org.sample.App</mainClass>
        </manifest>
      </archive>
    </configuration>
    <executions>
      <execution>
        <phase>package</phase>
        <goals>
          <goal>single</goal>
        </goals>
      </execution>
    </executions>
  </plugin>

Ersetzen org.sample.AppSie natürlich durch die Klasse, die Sie ausgeführt haben möchten. Kleiner Bonus, ich bin an assembly:singledie packagePhase gebunden , damit du nicht mehr rennen musst assembly:assembly. Einfach ausführen mvn installund die Baugruppe wird während des Standardaufbaus hergestellt.

Aktualisieren Sie daher Ihre pom.xml mit der oben angegebenen Konfiguration und führen Sie sie aus mvn clean install. Dann CD in das targetVerzeichnis und versuchen Sie es erneut:

java -jar logmanager-0.1.0-jar-with-dependencies.jar

Wenn Sie eine Fehlermeldung erhalten, aktualisieren Sie bitte Ihre Frage damit und veröffentlichen Sie den Inhalt der META-INF/MANIFEST.MFDatei und den relevanten Teil Ihrer pom.xml(die Plugins-Konfigurationsteile). Bitte posten Sie auch das Ergebnis von:

java -cp logmanager-0.1.0-jar-with-dependencies.jar com.gorkwobble.logmanager.LogManager

um zu demonstrieren, dass es in der Befehlszeile gut funktioniert (unabhängig davon, was Eclipse sagt).

EDIT: Für Java 6 müssen Sie das Maven-Compiler-Plugin konfigurieren. Fügen Sie dies Ihrer pom.xml hinzu:

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
      <source>1.6</source>
      <target>1.6</target>
    </configuration>
  </plugin>

4
Danke für deine Kommentare! Ich habe meine pom.xml wie angegeben geändert. Wenn ich mvn clean install ausführe, erhalte ich eine Reihe von Kompilierungsfehlern aus meinem Code, die besagen, dass Anmerkungen usw. in -source 1.3 nicht unterstützt werden. Ich verwende jdk1.6 und es wird in Eclipse kompiliert. Ich bin mir nicht sicher, wie der 1.3 eingeführt wurde. Vielleicht ist eine der Bibliotheksversionen im Pom-Snippet eine ältere?
RMorrisey

Vielen Dank! Ich habe die 1.3-Ausgabe hinter mich gebracht. Ich musste auch die junit4-Abhängigkeit zu meinem POM hinzufügen. Ich arbeite an der Fehlerbehebung bei anderen Dingen. Wenn ich nicht weiterkomme, werde ich wieder posten! Wenn ich das Glas zum Laufen bringe, werde ich dies als Antwort markieren. Mein aktueller POM wird in der obigen Frage aktualisiert.
RMorrisey

Gibt es eine Möglichkeit, die Ressourcen aus der generierten JAR-Datei auszuschließen?

2
Ist es möglich, dass das resultierende Glas einen "normalen" Namen hat?
Daniil Shevelev

1
Ich fand auch diesen Sonatype-Blog-Beitrag nützlich

15

Die Antwort von Pascal Thivent hat mir auch geholfen. Aber wenn Sie Ihre Plugins im verwalten <pluginManagement>Elemente, haben Sie die Baugruppe wieder außerhalb des Plug - ins Management zu definieren, oder auch die Abhängigkeiten sind nicht im Glas verpackt , wenn Sie laufen mvn install.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>jar</packaging>


    <build>
        <pluginManagement>
            <plugins>

                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.1</version>
                    <configuration>
                        <source>1.6</source>
                        <target>1.6</target>
                    </configuration>
                </plugin>

                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-assembly-plugin</artifactId>
                    <version>2.4</version>
                    <configuration>
                        <archive>
                            <manifest>
                                <mainClass>main.App</mainClass>
                            </manifest>
                        </archive>
                        <descriptorRefs>
                            <descriptorRef>jar-with-dependencies</descriptorRef>
                        </descriptorRefs>
                    </configuration>
                    <executions>
                        <execution>
                            <id>make-assembly</id>
                            <phase>package</phase>
                            <goals>
                                <goal>single</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>

            </plugins>

        </pluginManagement>

        <plugins> <!-- did NOT work without this  -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
            </plugin>
        </plugins>

    </build>


    <dependencies>
       <!--  dependencies commented out to shorten example -->
    </dependencies>

</project>

1
Danke Mike, es hat mir geholfen. Anfangs wurde mein Paket ohne Verwendung von <pluginManagement> generiert. Aber Eclipse hat in pom.xml "maven - Plugin-Ausführung, die nicht vom Lebenszyklus abgedeckt wird" einen Fehler gemeldet. Was mich ablenkt. Um dies zu lösen, habe ich <pluginManagement> hinzugefügt. Jetzt ist der Eclipse-Fehler verschwunden, aber mein Paket wurde nicht mehr erstellt. Ihr obiger Ausschnitt von Pom hat für mich funktioniert. :)
shashaDenovo

2
Dies war nützlich. Bei Verwendung von <pluginManagement> funktioniert die Top-Antwort nicht.
Ininprsr

5

Wenn Sie das Assembly-Ziel für das Paket nicht ausführen möchten, können Sie den nächsten Befehl verwenden:

mvn package assembly:single

Hier ist Paket Schlüsselwort.


-1

Klicken Sie mit der rechten Maustaste auf das Projekt und geben Sie Maven Build, Maven Clean, Maven Generate Resource und Maven Install an. Die JAR-Datei wird automatisch generiert.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.