Ist es möglich, ein Java anzugeben classpath
, das eine JAR-Datei enthält, die in einer anderen JAR-Datei enthalten ist?
Ist es möglich, ein Java anzugeben classpath
, das eine JAR-Datei enthält, die in einer anderen JAR-Datei enthalten ist?
Antworten:
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). Das erste ist One-Jar , das einen speziellen Klassenlader verwendet, um das Verschachteln von Gläsern zu ermöglichen. Das zweite ist UberJar (oder Shade ), das die enthaltenen Bibliotheken explodiert und alle Klassen in das Top-Level-Jar legt.
Ich sollte auch erwähnen, dass UberJar und Shade Plugins für Maven1 bzw. 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).
Sie möchten diese Lösungen zum Explodieren von JAR-Inhalten NICHT verwenden. Sie machen es definitiv schwieriger, Dinge zu sehen (da alles auf der gleichen Ebene explodiert ist). Darüber hinaus kann es zu Namenskonflikten kommen (sollte nicht auftreten, wenn Benutzer geeignete Pakete verwenden, dies kann jedoch nicht immer kontrolliert werden).
Die gewünschte Funktion ist eine der 25 besten Sun-RFEs : RFE 4648386 , die Sun in ihrer unendlichen Weisheit als von niedriger Priorität eingestuft hat. Wir können nur hoffen, dass Sun aufwacht ...
In der Zwischenzeit ist die beste Lösung, auf die ich gestoßen bin (die Sun gerne im JDK kopieren würde), die Verwendung des benutzerdefinierten Klassenladeprogramms JarClassLoader .
activation.jar
).
Nach einigen Recherchen habe ich eine Methode gefunden, die keinen Maven oder eine Erweiterung / ein Programm eines Drittanbieters erfordert.
Sie können "Klassenpfad" in Ihrer Manifestdatei verwenden.
Beispielsweise:
Erstellen Sie die Manifestdatei MANIFEST.MF
Manifest-Version: 1.0
Created-By: Bundle
Class-Path: ./custom_lib.jar
Main-Class: YourMainClass
Kompilieren Sie alle Ihre Klassen und führen Sie sie aus jar cfm Testing.jar MANIFEST.MF *.class custom_lib.jar
c
steht für "Archiv erstellen". Gibt
f
an, dass Sie angeben möchten, dass die Datei
v
für eine ausführliche Eingabe bestimmt ist. Dies
m
bedeutet, dass wir eine benutzerdefinierte Manifestdatei übergeben
Stellen Sie sicher, dass Sie lib in das jar-Paket aufgenommen haben. Sie sollten in der Lage sein, jar auf normale Weise laufen zu lassen.
basierend auf: http://www.ibm.com/developerworks/library/j-5things6/
Alle anderen Informationen, die Sie über den Klassenpfad benötigen, finden Sie hier
custom_lib.jar
weggezogen bin , kann das Glas nicht mehr ausgeführt werden :(
Verwenden Sie das Tag " zipgroupfileset" (verwendet dieselben Attribute wie ein Tag " fileset" ). Es entpackt alle Dateien im Verzeichnis und fügt sie Ihrer neuen Archivdatei hinzu. Weitere Informationen: http://ant.apache.org/manual/Tasks/zip.html
Dies ist ein sehr nützlicher Weg, um das Problem von Glas zu Glas zu umgehen. Ich weiß, dass 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 Ihr mit Ant erstelltes Glas packen möchten, vergessen Sie all diesen Klassenpfad oder das Plugin 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>
Wenn Sie mit ant bauen (ich verwende ant von Eclipse), können Sie einfach die zusätzlichen JAR-Dateien hinzufügen, indem Sie zu ant sagen, um sie hinzuzufügen ... Nicht unbedingt die beste Methode, wenn Sie ein Projekt haben, das von mehreren Personen verwaltet wird, aber es funktioniert für ein Personenprojekt und ist einfach.
Mein Ziel beim Erstellen der JAR-Datei 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>
wo
<property name="external-lib-dir"
value="C:\...\eclipseWorkspace\Filter\external\...\lib" />
war das dir mit den externen Gläsern. Und das ist es...
Sie müssen dazu einen benutzerdefinierten Klassenladeprogramm oder eine Drittanbieter-Bibliothek erstellen, die dies unterstützt. Am besten extrahieren Sie das Glas aus der Laufzeit und fügen es dem Klassenpfad hinzu (oder lassen Sie es bereits zum Klassenpfad hinzufügen).
Ich benutze Maven für meine Java-Builds, die ein Plugin namens Maven Assembly Plugin haben .
Es macht das, was Sie verlangen, aber wie einige der anderen Vorschläge beschreiben - im Wesentlichen alle abhängigen Gläser explodieren lassen und sie zu einem einzigen Glas zusammenfassen
Wenn Sie über eine Eclpise-IDE verfügen, müssen Sie nur Ihre JAR exportieren und "Erforderliche Bibliotheken in generierte JAR packen" auswählen. eclipse fügt automatisch die erforderlichen abhängigen JARs zur generierten JAR hinzu und generiert einige benutzerdefinierte Eclipse-Klassenladeprogramme, die diese JARs automatisch laden.
Winstone ist ziemlich gut http://blog.jayway.com/2008/11/28/executable-war-with-winstone-maven-plugin/ . Aber nicht für komplexe Standorte. Und das ist eine Schande, denn alles, was es braucht, ist das Plugin einzuschließen.
Nun, es gibt einen sehr einfachen Weg, wenn Sie Eclipse verwenden.
Exportieren Sie Ihr Projekt als "Runnable" -JAR-Datei (klicken Sie in Eclipse mit der rechten Maustaste auf den Projektordner und wählen Sie "Exportieren ..."). Stellen Sie beim Konfigurieren der Exporteinstellungen sicher, dass Sie "Erforderliche Bibliotheken in generiertes Jar extrahieren" auswählen. Denken Sie daran, wählen Sie "Extrahieren ..." und nicht "Erforderliche Bibliotheken verpacken ...".
Zusätzlich : Sie müssen in Ihren Exporteinstellungen eine Ausführungskonfiguration auswählen. Sie können also jederzeit eine leere main () in einer Klasse erstellen und für Ihre Ausführungskonfiguration verwenden.
Es ist jedoch nicht garantiert , dass es 100% der Zeit funktioniert - da Sie eine Popup-Meldung sehen, in der Sie aufgefordert werden, die Lizenzen der enthaltenen Jar-Dateien zu überprüfen und etwas darüber, dass Signaturdateien nicht kopiert werden. Ich mache dies jedoch seit Jahren und bin nie auf ein Problem gestoßen.
Das Extrahieren in ein Uber-Verzeichnis funktioniert für mich, da wir alle root: \ java verwenden sollten und Outlets-Code in Paketen mit Versionierung haben sollten. Dh ca.tecreations-1.0.0. Das Signieren ist in Ordnung, da die Gläser von ihrem heruntergeladenen Speicherort intakt sind. Signaturen von Drittanbietern intakt, extrahieren Sie nach c: \ java. Da ist mein Projektverzeichnis. Führen Sie den Launcher aus, also java -cp c: \ java Launcher