it-swarm.com.de

Abhängigkeiten in ein Glas mit Maven aufnehmen

Gibt es eine Möglichkeit, Maven (2.0.9) zu zwingen, alle Abhängigkeiten in einer einzigen JAR-Datei zu berücksichtigen?

Ich habe ein Projekt, das in eine einzige JAR-Datei erstellt wird. Ich möchte, dass die Klassen aus Abhängigkeiten auch in das Glas kopiert werden.

Update: Ich weiß, dass ich nicht einfach eine JAR-Datei in eine JAR-Datei einfügen kann. Ich suche nach einer Möglichkeit, die als Abhängigkeiten angegebenen Gläser zu entpacken und die Klassendateien in meinen Behälter zu packen.

289
racer

Sie können dies mit Hilfe des Plugins maven-Assembly mit dem Deskriptor "jar-with-dependencies" tun. Hier ist der relevante Teil aus einer unserer pom.xml-Dateien, der dies ausführt:

  <build>
    <plugins>
      <!-- any other plugins -->
      <plugin>
        <artifactId>maven-Assembly-plugin</artifactId>
        <executions>
          <execution>
            <phase>package</phase>
            <goals>
              <goal>single</goal>
            </goals>
          </execution>
        </executions>
        <configuration>
          <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
          </descriptorRefs>
        </configuration>
      </plugin>
    </plugins>
  </build>
417
John Stauffer

Bei Maven 2 ist dies der richtige Weg, wenn Sie das Maven2 Assembly Plugin verwenden, das/die über eine vordefinierte Deskriptordatei verfügt und dies einfach in der Befehlszeile verwenden könnte:

mvn Assembly:assembly -DdescriptorId=jar-with-dependencies

Wenn Sie diese jar-Datei ausführbar machen möchten, fügen Sie einfach die auszuführende Hauptklasse der Plug-In-Konfiguration hinzu:

<plugin>
  <groupId>org.Apache.maven.plugins</groupId>
  <artifactId>maven-Assembly-plugin</artifactId>
  <configuration>
    <archive>
      <manifest>
        <mainClass>my.package.to.my.MainClass</mainClass>
      </manifest>
    </archive>
  </configuration>
</plugin>

Wenn Sie diese Assembly als Teil des normalen Erstellungsprozesses erstellen möchten, müssen Sie das Ziel single oder directory-single (das Ziel Assembly sollte NUR von der Befehlszeile aus ausgeführt werden) an eine Lebenszyklusphase binden (package macht Sinn), etwa so:

<plugin>
  <groupId>org.Apache.maven.plugins</groupId>
  <artifactId>maven-Assembly-plugin</artifactId>
  <executions>
    <execution>
      <id>create-my-bundle</id>
      <phase>package</phase>
      <goals>
        <goal>single</goal>
      </goals>
      <configuration>
        <descriptorRefs>
          <descriptorRef>jar-with-dependencies</descriptorRef>
        </descriptorRefs>
        ...
      </configuration>
    </execution>
  </executions>
</plugin>

Passen Sie das configuration-Element an Ihre Bedürfnisse an (z. B. mit dem Manifestmaterial wie gesprochen).

123
Pascal Thivent

Wenn Sie eine ausführbare JAR-Datei erstellen möchten, müssen Sie auch die Hauptklasse festlegen. Also sollte die volle Konfiguration sein.

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

Sie können die neu erstellte Dose mit einem <classifier>-Tag verwenden.

<dependencies>
    <dependency>
        <groupId>your.group.id</groupId>
        <artifactId>your.artifact.id</artifactId>
        <version>1.0</version>
        <type>jar</type>
        <classifier>jar-with-dependencies</classifier>
    </dependency>
</dependencies>
14
lasantha

Es gibt das Schatten-Maven-Plugin . Es kann verwendet werden, um package und umbenennen Abhängigkeiten (um Abhängigkeitsprobleme im Klassenpfad zu vermeiden).

13
Thomas Jung

Wenn Sie (wie ich) den oben beschriebenen Ansatz jar-with-dependencies nicht besonders mögen, ist die Maven-Lösung, die ich am liebsten baue, einfach ein WAR-Projekt, Selbst wenn es nur eine eigenständige Java-Anwendung, die Sie erstellen:

  1. Erstellen Sie ein normales Maven-Jar-Projekt, das Ihre Jar-Datei (ohne die Abhängigkeiten) erstellt.

  2. Richten Sie außerdem ein Maven-Kriegsprojekt ein (mit nur einer leeren Datei src/main/webapp/WEB-INF/web.xml , die eine Warnung/einen Fehler im Maven-build verhindert), die nur Ihre jar-project als Abhängigkeit, und machen Sie Ihr jar-project zu einem <module> unter Ihrem Kriegsprojekt. (Dieses Kriegsprojekt ist nur ein einfacher Trick, um alle Abhängigkeiten Ihrer JAR-Dateien in eine Zip-Datei zu packen.)

  3. Erstellen Sie das Kriegsprojekt, um die Kriegsdatei zu erstellen.

  4. Benennen Sie Ihre .war-Datei im Implementierungsschritt einfach in * .Zip um und entpacken Sie sie.

Sie sollten jetzt ein lib-Verzeichnis (das Sie verschieben können, wohin Sie wollen) mit Ihrem jar und allen Abhängigkeiten haben, die Sie zum Ausführen Ihrer Anwendung benötigen:

Java -cp 'path/lib/*' MainClass

(Der Platzhalter im Klassenpfad funktioniert in Java-6 oder höher.)

Ich denke, dies ist sowohl einfacher in maven einzurichten (Sie müssen sich nicht mit dem Assembly-Plugin herumschlagen), als auch die Anwendungsstruktur klarer sehen (Sie sehen die Versionsnummern aller abhängigen Gläser in der einfachen Ansicht und) Vermeiden Sie, alles in einer einzigen Jar-Datei zu verstopfen).

12
Rop

http://fiji.sc/Uber-JAR bietet eine hervorragende Erklärung für die Alternativen: 

Es gibt drei gängige Methoden zum Erstellen eines Uber-JAR:

  1. Nicht schattiert Entpacken Sie alle JAR-Dateien und packen Sie sie anschließend in ein einzelnes JAR .
    • Pro: Funktioniert mit dem Standardklassenlader von Java.
    • Con: Dateien, die in mehreren JAR-Dateien mit demselben Pfad vorhanden sind (z. B. META-INF/services/javax.script.ScriptEngineFactory), überschreiben eine ein anderes, was zu fehlerhaftem Verhalten führt.
    • Werkzeuge: Maven Assembly Plugin, Classworlds Uberjar
  2. Schattiert Gleich wie nicht schattiert, aber alle Pakete aller Abhängigkeiten umbenannt (d. H. "Schatten") .
    • Pro: Funktioniert mit Javas Standardklassenlader . Vermeidet einige (nicht alle) Abhängigkeitsversionen.
    • Con: Dateien in mehreren JAR-Dateien mit demselben Pfad (z. B. META-INF/services/javax.script.ScriptEngineFactory) vorhanden ist, wird eine .__ überschrieben. ein anderes, was zu fehlerhaftem Verhalten führt.
    • Werkzeuge: Maven Shade Plugin
  3. JAR JARs. Die endgültige JAR-Datei enthält die anderen JAR-Dateien, die in ..__ eingebettet sind.
    • Pro: Vermeidet Konflikte mit Abhängigkeitsversionen. Alles Ressourcendateien bleiben erhalten.
    • Con: Muss ein spezielles .__ bündeln. "Bootstrap" Classloader, um Java das Laden von Klassen aus der .__ zu ermöglichen. umschlossene JAR-Dateien. Das Debuggen von Klassenladerproblemen wird komplexer.
    • Extras: Eclipse-JAR-Dateiexporter, One-JAR.
9
André Valenti

Meine endgültige Lösung für Eclipse Luna und m2Eclipse: Custom Classloader (nur 5 Klassen herunterladen und Ihrem Projekt hinzufügen) : Http://git.Eclipse.org/c/jdt/Eclipse.jdt. Englisch: www.sig.biz/site/en/medien/medien_/...bloc_690.jsp% 20in% 20jar% 20loader/org/Eclipse/jdt/internal/jarinjarloader/ ; schnell;

<project.mainClass>org.Eclipse.jdt.internal.jarinjarloader.JarRsrcLoader</project.mainClass> <project.realMainClass>my.Class</project.realMainClass>

In JIJConstants "Rsrc-Class-Path" zu "Class-Path" bearbeiten
mvn clean abhängigkeit: copy-dependencies-paket 
erstellt ein jar mit Abhängigkeiten im lib-Ordner mit einem dünnen Classloader 

<build>
    <resources>
        <resource>
            <directory>src/main/Java</directory>
            <includes>
                <include>**/*.Java</include>
                <include>**/*.properties</include>
            </includes>
        </resource>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
            <includes>
                <include>**/*</include>
            </includes>
            <targetPath>META-INF/</targetPath>
        </resource>
        <resource>
            <directory>${project.build.directory}/dependency/</directory>
            <includes>
                <include>*.jar</include>
            </includes>
            <targetPath>lib/</targetPath>
        </resource>
    </resources>
<pluginManagement>
        <plugins>

            <plugin>
                <groupId>org.Apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <configuration>
                    <archive>
                        <manifest>
                            <addClasspath>true</addClasspath>
                            <mainClass>${project.mainClass}</mainClass>
                            <classpathPrefix>lib/</classpathPrefix>
                        </manifest>

                        <manifestEntries>
                            <Rsrc-Main-Class>${project.realMainClass}  </Rsrc-Main-Class>
                            <Class-Path>./</Class-Path>
                        </manifestEntries>

                    </archive>
                </configuration>
            </plugin>
<plugin>
                <groupId>org.Apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <executions>
                    <execution>
                        <id>copy-dependencies</id>
                        <phase>package</phase>
                        <goals>
                            <goal>copy-dependencies</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </pluginManagement>
</build>
4
        <!-- Method 1 -->
        <!-- Copy dependency libraries jar files to a separated LIB folder -->
        <plugin>
            <groupId>org.Apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <configuration>
                <outputDirectory>${project.build.directory}/lib</outputDirectory>
                <excludeTransitive>false</excludeTransitive> 
                <stripVersion>false</stripVersion>
            </configuration>
            <executions>
                <execution>
                    <id>copy-dependencies</id>
                    <phase>package</phase>
                    <goals>
                        <goal>copy-dependencies</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        <!-- Add LIB folder to classPath -->
        <plugin>
            <groupId>org.Apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>2.4</version>
            <configuration>
                <archive>
                    <manifest>
                        <addClasspath>true</addClasspath>
                        <classpathPrefix>lib/</classpathPrefix>
                    </manifest>
                </archive>
            </configuration>
        </plugin>


        <!-- Method 2 -->
        <!-- Package all libraries classes into one runnable jar -->
        <plugin>
            <artifactId>maven-Assembly-plugin</artifactId>
            <executions>
              <execution>
                <phase>package</phase>
                <goals>
                  <goal>single</goal>
                </goals>
              </execution>
            </executions>
            <configuration>
              <descriptorRefs>
                <descriptorRef>jar-with-dependencies</descriptorRef>
              </descriptorRefs>
            </configuration>
        </plugin>            
3
Leslie Li

Wenn Sie Maven beiseite legen, können Sie JAR-Bibliotheken in den Hauptbehälter geben, müssen jedoch einen eigenen Klassenladeprogramm verwenden.

Überprüfen Sie dieses Projekt: One-JAR Linktext

1
medopal

Dieser Beitrag ist vielleicht ein bisschen alt, aber ich hatte in letzter Zeit auch das gleiche Problem. Die erste von John Stauffer vorgeschlagene Lösung ist gut, aber ich hatte einige Probleme, als ich in diesem Frühling arbeite. Die Abhängigkeitsgefäße des Frühlings, die ich verwende, haben einige Eigenschaftendateien und eine XML-Schema-Deklaration, die dieselben Pfade und Namen verwenden. Obwohl diese Gläser aus denselben Versionen stammen, hat das Maven-Goal jar-with-dependencies diese Datei mit der zuletzt gefundenen Datei überschrieben. 

Am Ende konnte die Anwendung nicht gestartet werden, da die Springgläser die korrekten Eigenschaftendateien nicht finden konnten. In diesem Fall haben die Lösungsvorschläge von Rop mein Problem gelöst.

Seitdem existiert auch das Spring-Boot-Projekt. Es ist eine sehr coole Art, dieses Problem zu lösen, indem ein Maven-Ziel bereitgestellt wird, das das Paketziel überlastet und einen eigenen Klassenlader bereitstellt. Siehe Spring Boots Referenzhandbuch

0

Vielen Dank Ich habe unten ein Snippet in POM.xml-Datei hinzugefügt und Mp-Problem gelöst und Fette Jar-Datei erstellen, die alle abhängigen jars enthält.

<plugin>
    <artifactId>maven-Assembly-plugin</artifactId>
        <executions>
            <execution>
                <phase>package</phase>
                <goals>
                    <goal>single</goal>
                </goals>
            </execution>
        </executions>
        <configuration>
            <descriptorRefs>
                <descriptorRef>dependencies</descriptorRef>
            </descriptorRefs>
        </configuration>
    </plugin>
</plugins>
0
Rajeev Rathor

Schau dir diese Antwort an:

Ich erstelle ein Installationsprogramm, das als Java-JAR-Datei ausgeführt wird und WAR- und JAR-Dateien an geeigneten Stellen im Installationsverzeichnis entpacken muss. Das Abhängigkeits-Plugin kann in der Paketphase mit dem Kopierziel verwendet werden und lädt alle Dateien im Maven-Repository (einschließlich WAR-Dateien) herunter und schreibt sie dort, wo Sie sie benötigen. Ich habe das Ausgabeverzeichnis in $ {project.build.directory}/classes geändert und das Endergebnis ist, dass die normale JAR-Task meine Dateien enthält. Ich kann sie dann extrahieren und in das Installationsverzeichnis schreiben.

<plugin>
<groupId>org.Apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
    <execution>
        <id>getWar</id>
        <phase>package</phase>
        <goals>
            <goal>copy</goal>
        </goals>
        <configuration>
            <artifactItems>
                <artifactItem>
                    <groupId>the.group.I.use</groupId>
                    <artifactId>MyServerServer</artifactId>
                    <version>${env.Java_SERVER_REL_VER}</version>
                    <type>war</type>
                    <destFileName>myWar.war</destFileName>
                </artifactItem>
            </artifactItems>
            <outputDirectory>${project.build.directory}/classes</outputDirectory>
        </configuration>
    </execution>
</executions>

0
millebi