Ist es möglich, ein Java classpath
anzugeben, das eine JAR-Datei enthält, die in einer anderen JAR-Datei enthalten ist?Klassenpfad einschließlich JAR in einem JAR
Antwort
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).
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.
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).
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.
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
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) –
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.
Benennungskonflikte sind tatsächlich fast garantiert mit Sachen wie log4j Konfiguration und Lizenztexten passieren. –
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
+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'). –
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>
für mich funktioniert netter Trick. – Lucke
Winstone ist ziemlich gut http://blog.jayway.com/2008/11/28/executable-war-with-winstone-maven-plugin/. Aber nicht für komplexe Websites. Und das ist eine Schande, denn es ist nur nötig, das Plugin einzubinden.
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 ...
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
siehe http://docs.oracle.com/javase/tutorial/deployment/jar/downman.html – jntme
Das funktioniert sehr gut. – Deian
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
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.
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.
- 1. Klassenpfad-Ressource in jar
- 2. Einschließlich Bibliotheken in jar
- 3. JAR-Klassenpfad in UBUNTU hinzufügen
- 4. Java-Export-JAR einschließlich Bibliotheken
- 5. Fehler einschließlich Android-DirectionalViewPager .jar in Eclipse
- 6. JUnit run Tests in einem JAR
- 7. Qt Creator 3.2.1 einschließlich .jar für Android
- 8. Wie man mehrere Jar-Dateien in Klassenpfad in Linux hinzufügen
- 9. umfassen externe jar wenn java -jar
- 10. Kann der Klassenpfad in der MANIFEST.MF nur JAR-Dateien enthalten?
- 11. jar bundle und sein Klassenpfad in ServiceMix-karaf
- 12. Erstellen Sie ausführbare Jar mit Einstiegspunkt in einem eingebetteten Jar
- 13. JAR versteckt in EXE?
- 14. ojdbc14.jar vs ojdbc6.jar
- 15. Jar Dateiabhängigkeiten in Java 1.4
- 16. jar Kompilieren Runtime.getRuntime.exec() Volles Verzeichnis in jar
- 17. Bootstrap ausführbare JAR-Datei im Klassenpfad beim Start des Servers
- 18. wie ich meine externe JAR-Datei zum Klassenpfad hinzufügen
- 19. Gradle Jar Aufgabe zum Hinzufügen von Inhalten von JAR-Dateien in einem Verzeichnis
- 20. Java Reflektions- und Manifest-Datei in jar
- 21. Einschließlich Android-Aktivitäten (und ihre Layouts) in JAR-Dateien
- 22. JAVA: einschließlich Dateien in jar und wie Sie darauf zugreifen
- 23. Laden xslt Datei von jar lädt jar selbst statt xslt
- 24. Kann ich den Klassenpfad zum Überschreiben einer Datei in einem ausgeführten jar verwenden?
- 25. Import Klassendatei aus bestimmten jar
- 26. Unicode in Jar Ressourcen
- 27. NoClassDefFoundError in jar
- 28. Jar in DLL ersetzen
- 29. Problem mit Pfaden in einem Java-Jar
- 30. Analysiere JAR-Abhängigkeiten in einem Java-Projekt
Also hier sind wir, 5 Jahre später. Es sieht so aus, als ob das immer noch wahr ist. Sehr traurig :( – T3rm1
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
Das ist in manchen Situationen nicht möglich Ihr nutzt JCE-Implementierungen wie BouncyCastle, die signiert werden müssen – debuti