it-swarm.com.de

Klassenpfad einschließlich JAR in einer JAR

Ist es möglich, ein Java classpath anzugeben, das eine JAR-Datei enthält, die in einer anderen JAR-Datei enthalten ist?

127
Paul Reiners

Wenn Sie versuchen, eine einzelne JAR-Datei zu erstellen, die Ihre Anwendung und die erforderlichen Bibliotheken enthält, gibt es zwei Möglichkeiten (die mir bekannt sind), dies zu tun. Das erste ist One-Jar , das einen speziellen Klassenlader verwendet, um das Verschachteln von Gläsern zu ermöglichen. Das zweite ist berJar (oder Shade ), das die enthaltenen Bibliotheken auflöst und alle Klassen in das Top-Level-Jar einsetzt.

Ich sollte auch erwähnen, dass UberJar und Shade Plugins für Maven1 bzw. Maven2 sind. Wie weiter unten erwähnt, können Sie auch das Assembly-Plugin verwenden (das in Wirklichkeit viel leistungsfähiger ist, aber viel schwieriger zu konfigurieren ist).

91
Steve Moyer

Sie möchten diese "JAR-Inhalt auflösen" -Lösungen NICHT verwenden. Sie erschweren es definitiv, Dinge zu sehen (da alles auf der gleichen Ebene explodiert). Darüber hinaus kann es zu Namenskonflikten kommen (sollte nicht auftreten, wenn Benutzer ordnungsgemäße Pakete verwenden, aber Sie können dies nicht immer steuern).

Die von Ihnen gewünschte Funktion ist eine der Top 25 Sun RFEs : RFE 4648386 , die Sun in ihrer unendlichen Weisheit als mit niedriger Priorität eingestuft hat. Wir können nur hoffen, dass die Sonne aufwacht ...

In der Zwischenzeit ist die beste Lösung, auf die ich gestoßen bin (die Sun gerne im JDK kopieren würde), den benutzerdefinierten Klassenlader JarClassLoader zu verwenden.

50
Bruce Willis

Nach einigen Recherchen habe ich eine Methode gefunden, die keinen Maven oder eine Erweiterung/ein Programm von Drittanbietern erfordert.

Sie können "Class-Path" in Ihrer Manifest-Datei verwenden.

Beispielsweise:

Erstellen Sie die Manifestdatei MANIFEST.MF

Manifest-Version: 1.0
Created-By: Bundle
Class-Path: ./custom_lib.jar
Main-Class: YourMainClass

Kompiliere alle deine Klassen und führe jar cfm Testing.jar MANIFEST.MF *.class custom_lib.jar

c steht für create archive f gibt an, dass Sie eine Datei angeben möchten. v ist für ausführliche Eingaben gedacht. m bedeutet, dass wir eine benutzerdefinierte Manifestdatei übergeben

Stellen Sie sicher, dass Sie lib im jar-Paket enthalten haben. Sie sollten in der Lage sein, jar auf normale Weise auszuführen.

basierend auf: http://www.ibm.com/developerworks/library/j-5things6/

alle weiteren informationen über den klassenpfad findest du hier

29
Tezar

Verwenden Sie das zipgroupfileset -Tag (verwendet dieselben Attribute wie ein Dateigruppen-Tag ); Es werden alle Dateien im Verzeichnis entpackt und zu Ihrer neuen Archivdatei hinzugefügt. Weitere Informationen: http://ant.Apache.org/manual/Tasks/Zip.html

Dies ist ein sehr nützlicher Weg, um das JAR-IN-A-JAR-Problem zu umgehen - ich weiß, weil ich genau diese StackOverflow-Frage gegoogelt habe, während ich versucht habe, herauszufinden, was zu tun ist. Wenn Sie ein Glas oder einen Ordner mit Gläsern in ein mit Ant erstelltes Glas packen möchten, vergessen Sie all diese Klassenpfade oder Plugin-Inhalte von Drittanbietern. Alles, was Sie tun müssen, ist Folgendes (in Ant):

<jar destfile="your.jar" basedir="Java/dir">
  ...
  <zipgroupfileset dir="dir/of/jars" />
</jar>
22
ecbrodie

Wenn Sie mit ant bauen (ich verwende ant von Eclipse), können Sie die zusätzlichen JAR-Dateien einfach hinzufügen, indem Sie ant sagen, um sie hinzuzufügen ... Dies ist nicht unbedingt die beste Methode, wenn Sie ein Projekt von mehreren Personen verwalten lassen, aber es funktioniert für ein Personenprojekt und ist einfach.

mein Ziel, das die JAR-Datei erstellt hat, war beispielsweise:

<jar destfile="${plugin.jar}" basedir="${plugin.build.dir}">
    <manifest>
        <attribute name="Author" value="ntg"/>
        ................................
        <attribute name="Plugin-Version" value="${version.entry.commit.revision}"/>
    </manifest>
</jar>

Ich habe nur eine Zeile hinzugefügt, um es zu machen:

<jar ....">
    <zipgroupfileset dir="${external-lib-dir}" includes="*.jar"/>
    <manifest>
        ................................
    </manifest>
</jar>

woher

<property name="external-lib-dir" 
          value="C:\...\eclipseWorkspace\Filter\external\...\lib" />

war das Verzeichnis mit den externen Gläsern. Und das ist es...

8
ntg

Nicht ohne einen eigenen Klassenlader zu schreiben. Sie können Gläser zum Klassenpfad des Glases hinzufügen, diese müssen sich jedoch nebeneinander befinden und dürfen nicht im Hauptglas enthalten sein.

6
Joe Skora

Dazu müssen Sie ein benutzerdefiniertes Klassenladeprogramm oder eine Bibliothek eines Drittanbieters erstellen, die dies unterstützt. Am besten extrahieren Sie die JAR-Datei aus der Laufzeit und fügen Sie sie dem Klassenpfad hinzu (oder lassen Sie sie bereits dem Klassenpfad hinzufügen).

2
James Schek

Wenn Sie über eine Eclpise-IDE verfügen, müssen Sie nur Ihre JAR-Datei exportieren und "Erforderliche Bibliotheken in generierte JAR-Datei packen" auswählen. Eclipse fügt automatisch die erforderlichen abhängigen JAR-Dateien in die generierte JAR-Datei ein sowie einige benutzerdefinierte Eclipse-Klassenladeprogramme, die diese JAR-Dateien automatisch laden.

2
amralieg

Ich benutze maven für meine Java Builds, die ein Plugin namens maven Assembly plugin haben.

Es macht, was Sie fragen, aber wie einige der anderen Vorschläge beschreiben - im Wesentlichen alle abhängigen Gläser explodieren und sie in einem einzigen Glas rekombinieren

2
Vinnie

Nun, es gibt eine sehr einfache Möglichkeit, wenn Sie Eclipse verwenden.

Exportieren Sie Ihr Projekt als ausführbare Jar-Datei (klicken Sie in Eclipse mit der rechten Maustaste auf den Projektordner, und wählen Sie "Exportieren ..." aus). Stellen Sie beim Konfigurieren der Exporteinstellungen sicher, dass Sie "Erforderliche Bibliotheken in generierte Jar extrahieren" auswählen. Denken Sie daran, wählen Sie "Extract ..." und not "Package required libraries ...".

Zusätzlich: Sie müssen in Ihren Exporteinstellungen eine Run-Konfiguration auswählen. Sie können also jederzeit ein leeres main () in einer Klasse erstellen und es für Ihre Ausführungskonfiguration verwenden.

Wie auch immer, es ist nicht garantiert , dass es 100% der Zeit funktioniert - Sie werden eine Popup-Nachricht sehen, die Sie auffordert, das zu überprüfen Lizenzen für die Jar-Dateien, die Sie einschließen, und etwas über das Nicht-Kopieren von Signaturdateien. Ich mache dies jedoch seit Jahren und bin nie auf ein Problem gestoßen.

1
CM_2014

Ich wollte raten, alle Dateien auf der gleichen Ebene zu extrahieren und dann ein Glas aus dem Ergebnis zu machen, da das Paketsystem sie sauber getrennt halten sollte. Das wäre der manuelle Weg, ich nehme an, dass die von Steve angegebenen Werkzeuge das gut machen werden.

1
PhiLho

Winstone ist ziemlich gut http://blog.jayway.com/2008/11/28/executable-war-with-winstone-maven-plugin/ . Aber nicht für komplexe Sites. Und das ist eine Schande, denn alles, was es braucht, ist das Plugin einzuschließen.

1
Jan Goyvaerts