2008-10-08 14 views

Antwort

85

Wenn Sie versuchen, ein einzelnes JAR zu erstellen, das Ihre Anwendung und die benötigten Bibliotheken enthält, gibt es dafür zwei Möglichkeiten (die ich kenne). Die erste ist One-Jar, die einen speziellen Classloader verwendet, um das Nesting von Gläsern zu ermöglichen. Die zweite ist (oder Shade), die die enthaltenen Bibliotheken auflöst und alle Klassen in die oberste Ebene einfügt.

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

+64

Also hier sind wir, 5 Jahre später. Es sieht so aus, als ob das immer noch wahr ist. Sehr traurig :( – T3rm1

+1

Der beste Weg, den ich jetzt weiß, ist die Verwendung von IntelliJ-Jar-Artefakten. Es extrahiert alle Klassen aus den abhängigen Gläsern und legt sie in Ihr einziges Glas. – enl8enmentnow

+1

Das ist in manchen Situationen nicht möglich Ihr nutzt JCE-Implementierungen wie BouncyCastle, die signiert werden müssen – debuti

6

Nicht ohne Ihren eigenen Klassenlader zu schreiben. Sie können dem Klassenpfad des JARs JAR-Dateien hinzufügen, diese müssen jedoch gemeinsam angeordnet sein und dürfen nicht im Hauptjar enthalten sein.

2

Sie müssen einen benutzerdefinierten Klassenlader erstellen, um dies zu tun, oder eine Bibliothek eines Drittanbieters, die dies unterstützt. Am besten extrahieren Sie das Jar aus der Laufzeitumgebung und fügen Sie sie dem Klassenpfad hinzu (oder fügen Sie sie dem Klassenpfad hinzu).

1

Ich war im Begriff zu empfehlen, alle Dateien auf der gleichen Ebene zu extrahieren, um dann ein Glas aus dem Ergebnis zu machen, da das Paketsystem sie ordentlich getrennt halten sollte. Das wäre der manuelle Weg, ich nehme an, die von Steve angegebenen Tools werden das gut machen.

2

Ich benutze Maven für meine Java-Builds, die ein Plugin namens maven assembly plugin hat.

Es tut, was Ihre Fragen, aber wie einige der anderen Vorschläge beschreiben - im Wesentlichen alle abhängigen Gläser explodieren und sie in einem einzigen Glas

+0

Das Maven Assembly Plugin ist ziemlich schmerzhaft zu benutzen ... UberJar und Shade sind Maven1 und Maven2 Plugins (eine Tatsache, die ich oben hätte erwähnen sollen) , und wird es jetzt tun) –

49

Sie nicht wollen, diese „explodieren JAR Inhalte“ Lösungen verwenden, rekombinieren. Sie machen es definitiv schwieriger, Dinge zu sehen (da alles auf der gleichen Ebene explodiert). Darüber hinaus könnte es zu Namenskonflikten kommen (sollte nicht passieren, wenn Leute richtige Pakete benutzen, aber Sie können das nicht immer kontrollieren).

Die Funktion, die Sie wollen, ist eine der top 25 Sun RFEs: RFE 4648386, die Sun in ihrer unendlichen Weisheit als niedrige Priorität bezeichnet hat. Wir können nur hoffen, dass Sun wacht ...

In der Zwischenzeit ist die beste Lösung, die ich (die ich möchte, dass Sun in das JDK kopieren würde) gefunden, ist die Verwendung der benutzerdefinierten Klasse Loader JarClassLoader.

+4

Benennungskonflikte sind tatsächlich fast garantiert mit Sachen wie log4j Konfiguration und Lizenztexten passieren. –

+1

Leider ist JarClassLoader GPLv3/kommerziell, also wird es wahrscheinlich nicht "von der Sonne kopiert (jetzt Orakel)", und kann nicht kommerziell genutzt werden, es sei denn, Sie haben den internen politischen Einfluss und Zeit, etwas gekauft zu bekommen. Ich stimme jedoch zu, dass Gläser, die auf dem aktuellen Verzeichnis barf sind, eine schlechte Sache sind. – Gus

+0

+1 für die Idee in dieser Antwort (obwohl ich nicht + 1'ing die Antwort selbst): Sie können keine signierte JAR-Datei neu packen, so dass diese Technik nicht in vielen Situationen (z. B. verwendet werden kann) Java 'activation.jar'). –

22

Verwenden des zipgroupfileset tag (verwendet gleiche Attribute wie ein fileset tag); Es wird alle Dateien im Verzeichnis entpacken und zu Ihrer neuen Archivdatei hinzufügen. Weitere Informationen: http://ant.apache.org/manual/Tasks/zip.html

Dies ist eine sehr nützliche Methode, um das Glas-in-a-jar Problem zu bekommen - ich weiß, weil ich genau diese Frage Stackoverflow gegoogelt habe bei dem Versuch, herauszufinden, was zu tun ist. Wenn Sie ein Glas oder einen Ordner von Gläsern in dem eine eingebauten Glas mit Ant verpacken wollen, dann vergessen Sie das alles Classpath oder Drittanbieter-Plug-Sachen, alles was Sie tun muß, ist dies (in Ant):

<jar destfile="your.jar" basedir="java/dir"> 
    ... 
    <zipgroupfileset dir="dir/of/jars" /> 
</jar> 
+0

für mich funktioniert netter Trick. – Lucke

8

Wenn Sie mit Ameise bauen (Ich verwende ant von Eclipse), können Sie einfach die zusätzliche JAR-Dateien hinzufügen durch zu ant sagen, um sie hinzuzufügen ... Nicht unbedingt die beste Methode, wenn Sie ein Projekt gepflegt haben von mehreren Personen, aber es funktioniert für Ein-Personen-Projekt und ist einfach.

zum Beispiel mein Ziel, dass die .jar-Datei war der Bau war:

<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> 

Habe ich nur eine Zeile zu machen:

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

wo

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

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

26

Nach einigen Recherchen habe ich eine Methode gefunden, die Maven oder eine Drittanbieter-Erweiterung/Programm nicht erfordert.

Sie können "Klassenpfad" in Ihrer Manifestdatei verwenden.

Zum Beispiel:

erstellen Manifest-Datei MANIFEST.MF

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

alle Klassen zusammenstellen und jar cfm Testing.jar MANIFEST.MF *.class custom_lib.jar

c Stände laufen erstellen Archiv f zeigt an, dass Sie Datei angeben möchten v ist für ausführliche Eingabe m bedeutet, dass wir pa benutzerdefinierte Manifest ss Datei

Seien Sie sicher, dass Sie lib in JAR-Paket enthalten. Sie sollten in der Lage sein, jar auf die übliche Weise auszuführen.

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

alle anderen Informationen, die Sie über die Klasse-Pfad brauchen Sie here

+0

siehe http://docs.oracle.com/javase/tutorial/deployment/jar/downman.html – jntme

+0

Das funktioniert sehr gut. – Deian

+14

Diese Antwort funktioniert * nicht *. aus dem oracle doc (über banane oben verlinkt): "Der Klassenpfad-Header verweist auf Klassen oder JAR-Dateien im lokalen Netzwerk, nicht auf JAR-Dateien innerhalb der JAR-Datei" – sebnukem

1

Nun finden, gibt es eine sehr einfache Art und Weise, wenn Sie von Eclipse verwenden.

Export Ihr Projekt als "Runnable" Jar-Datei (rechte Maustaste Projektordner von Eclipse aus, wählen Sie "Export ..."). Wenn Sie die Exporteinstellungen konfigurieren, achten Sie darauf, dass Sie die erforderlichen Bibliotheken in das generierte Glas extrahieren. Denken Sie daran, wählen Sie "Extract ..." und nicht "Paket erforderlichen Bibliotheken ...".

Zusätzlich: Sie müssen eine Laufkonfiguration in Ihren Exporteinstellungen auswählen. Sie könnten also immer eine leere main() in einer Klasse erstellen und sie für Ihre Laufkonfiguration verwenden.

Wie auch immer, es ist nicht garantiert 100% der Zeit zu arbeiten - wie Sie eine Pop-up-Meldung finden Sie, um sicherzustellen, überprüfen Sie die Lizenzen der Jar-Dateien, die Sie einschließen und etwas über Kopieren von Signaturdateien nicht. Allerdings mache ich das für Jahre und habe noch nie ein Problem festgestellt.

2

Wenn Sie über die IDE von eclpise verfügen, müssen Sie nur Ihr JAR exportieren und "Paket benötigte Bibliotheken in generiertes JAR" auswählen. Eclipse fügt automatisch die erforderlichen abhängigen JARs in das generierte JAR ein und generiert einige benutzerdefinierte Eclipse-Klassenladeprogramme, die diese JARs automatisch laden.

Verwandte Themen