Einfachste Möglichkeit, eine Version in einer JAR-Datei zusammenzuführen

74

Gibt es ein Tool oder Skript, mit dem mehrere JAR- Dateien einfach zu einer JAR-Datei zusammengeführt werden können? Ein Bonus wäre, das Manifest der Hauptdatei einfach festzulegen und ausführbar zu machen.

Der konkrete Fall ist ein Java-umstrukturiertes Textwerkzeug . Ich würde es gerne mit so etwas wie:

java -jar rst.jar

Soweit ich das beurteilen kann, gibt es keine Abhängigkeiten, was darauf hinweist, dass es kein einfaches Tool für einzelne Dateien sein sollte, aber die heruntergeladene ZIP-Datei enthält viele Bibliotheken.

      0  11-30-07 10:01   jrst-0.8.1/
    922  11-30-07 09:53   jrst-0.8.1/jrst.bat
    898  11-30-07 09:53   jrst-0.8.1/jrst.sh
   2675  11-30-07 09:42   jrst-0.8.1/readmeEN.txt
 108821  11-30-07 09:59   jrst-0.8.1/jrst-0.8.1.jar
   2675  11-30-07 09:42   jrst-0.8.1/readme.txt
      0  11-30-07 10:01   jrst-0.8.1/lib/
  81508  11-30-07 09:49   jrst-0.8.1/lib/batik-util-1.6-1.jar
2450757  11-30-07 09:49   jrst-0.8.1/lib/icu4j-2.6.1.jar
 559366  11-30-07 09:49   jrst-0.8.1/lib/commons-collections-3.1.jar
  83613  11-30-07 09:49   jrst-0.8.1/lib/commons-io-1.3.1.jar
 207723  11-30-07 09:49   jrst-0.8.1/lib/commons-lang-2.1.jar
  52915  11-30-07 09:49   jrst-0.8.1/lib/commons-logging-1.1.jar
 260172  11-30-07 09:49   jrst-0.8.1/lib/commons-primitives-1.0.jar
 313898  11-30-07 09:49   jrst-0.8.1/lib/dom4j-1.6.1.jar
1994150  11-30-07 09:49   jrst-0.8.1/lib/fop-0.93-jdk15.jar
  55147  11-30-07 09:49   jrst-0.8.1/lib/activation-1.0.2.jar
 355030  11-30-07 09:49   jrst-0.8.1/lib/mail-1.3.3.jar
  77977  11-30-07 09:49   jrst-0.8.1/lib/servlet-api-2.3.jar
 226915  11-30-07 09:49   jrst-0.8.1/lib/jaxen-1.1.1.jar
 153253  11-30-07 09:49   jrst-0.8.1/lib/jdom-1.0.jar
  50789  11-30-07 09:49   jrst-0.8.1/lib/jewelcli-0.41.jar
 324952  11-30-07 09:49   jrst-0.8.1/lib/looks-1.2.2.jar
 121070  11-30-07 09:49   jrst-0.8.1/lib/junit-3.8.1.jar
 358085  11-30-07 09:49   jrst-0.8.1/lib/log4j-1.2.12.jar
  72150  11-30-07 09:49   jrst-0.8.1/lib/logkit-1.0.1.jar
 342897  11-30-07 09:49   jrst-0.8.1/lib/lutinwidget-0.9.jar
2160934  11-30-07 09:49   jrst-0.8.1/lib/docbook-xsl-nwalsh-1.71.1.jar
 301249  11-30-07 09:49   jrst-0.8.1/lib/xmlgraphics-commons-1.1.jar
  68610  11-30-07 09:49   jrst-0.8.1/lib/sdoc-0.5.0-beta.jar
3149655  11-30-07 09:49   jrst-0.8.1/lib/xalan-2.6.0.jar
1010675  11-30-07 09:49   jrst-0.8.1/lib/xercesImpl-2.6.2.jar
 194205  11-30-07 09:49   jrst-0.8.1/lib/xml-apis-1.3.02.jar
  78440  11-30-07 09:49   jrst-0.8.1/lib/xmlParserAPIs-2.0.2.jar
  86249  11-30-07 09:49   jrst-0.8.1/lib/xmlunit-1.1.jar
 108874  11-30-07 09:49   jrst-0.8.1/lib/xom-1.0.jar
  63966  11-30-07 09:49   jrst-0.8.1/lib/avalon-framework-4.1.3.jar
 138228  11-30-07 09:49   jrst-0.8.1/lib/batik-gui-util-1.6-1.jar
 216394  11-30-07 09:49   jrst-0.8.1/lib/l2fprod-common-0.1.jar
 121689  11-30-07 09:49   jrst-0.8.1/lib/lutinutil-0.26.jar
  76687  11-30-07 09:49   jrst-0.8.1/lib/batik-ext-1.6-1.jar
 124724  11-30-07 09:49   jrst-0.8.1/lib/xmlParserAPIs-2.6.2.jar

Wie Sie sehen können, ist es etwas wünschenswert, dies nicht manuell tun zu müssen.

Bisher habe ich nur AutoJar und ProGuard ausprobiert, die beide ziemlich einfach zum Laufen zu bringen waren. Es scheint, dass es ein Problem mit dem konstanten Pool in den JAR-Dateien gibt.

Anscheinend ist jrst leicht kaputt, also werde ich versuchen, es zu reparieren. Die Maven- pom.xml Datei war anscheinend auch kaputt, also muss ich das reparieren, bevor ich jrst repariere ... Ich fühle mich wie ein Bug-Magnet :-)


Update: Ich bin nie dazu gekommen, diese Anwendung zu reparieren, habe aber den "Runnable JAR-Exportassistenten" von Eclipse überprüft, der auf einer fetten JAR basiert. Ich fand es sehr einfach, meinen eigenen Code bereitzustellen.

Einige der anderen hervorragenden Vorschläge sind möglicherweise besser für Builds in einer Nicht-Eclipse-Umgebung. Oss sollte wahrscheinlich einen guten Build mit Ant erstellen . (Maven hat mir bisher nur Schmerzen bereitet, aber andere lieben es.)

tovare
quelle
One-Jar
Stephen Denne
Fat Jar Eclipse Plugin
Stephen Denne

Antworten:

34

Eclipse 3.4 JDTs Runnable JAR-Exportassistent.

In Eclipse 3.5 wurde dies erweitert. Jetzt können Sie auswählen, wie Sie Ihre referenzierten JAR-Dateien behandeln möchten.

Stephen Denne
quelle
Können Sie überprüfen, ob die generierten Ant-Skripte verwendbar sind? Es gab früher ein Problem mit absoluten Dateipfaden anstelle von relativen.
Thorbjørn Ravn Andersen
62

Ameisen machen zipfilesetden Job

<jar id="files" jarfile="all.jar">
    <zipfileset src="first.jar" includes="**/*.java **/*.class"/>
    <zipfileset src="second.jar" includes="**/*.java **/*.class"/>
</jar>
akuhn
quelle
1
+1, da dies auch das Hinzufügen von <manifest /> -Tags und das Festlegen der Hauptklasse ermöglicht.
Shirkrin
Wäre es irgendwie möglich, dies für alle JAR-Dateien in einem Verzeichnis zu tun? Wäre sehr ordentlich. Vermeiden Sie es, build.xml zu aktualisieren, wenn sich Bibliotheken ändern.
Frans Lundberg
3
Versuchen Sie diesen Ansatz, Sie müssen sich keine Gedanken über das Hinzufügen neuer Gläser machen: github.com/anupamsaini/Trie/blob/master/src/build.xml#L42
Anupam Saini
27

Nachdem ich einige verschiedene Lösungen ausprobiert hatte, fand ich, dass One-JAR am einfachsten zu handhaben ist, und habe es geschafft, genau das zu tun: eine einzige ausführbare JAR zu erstellen, die alles enthält, was ich brauche.

One-JAR verwendet einen benutzerdefinierten Klassenladeprogramm, das in verschachtelten Ressourcen navigieren kann. Schauen Sie sich die .bat-Datei im Download an. Sie sieht aus wie org.codelutin.jrst.JRST in jrst-0.8.1.jar ist die Hauptklasse, daher sollte Ihr Manifest folgendermaßen aussehen:

Main-Class: com.simontuffs.onejar.Boot
One-Jar-Main-Class: org.codelutin.jrst.JRST

Das wirklich Coole ist, dass One-JAR die Weitergabe von Befehlszeilenargumenten für Sie übernimmt. Der Klassenpfad wird vom benutzerdefinierten Klassenladeprogramm verwaltet, sofern alle benötigten Ressourcen in einer einzigen JAR gebündelt sind.

Der einfachste Weg, One-JAR zu verwenden, ist mit Ameise; Es gibt eine benutzerdefinierte "Ein-Glas" -Ant-Aufgabe, die wie folgt funktioniert (vorausgesetzt, Ihr Manifest heißt "rst.mf"):

<target name="jar-rst">
    <one-jar destfile="rst.jar" manifest="rst.mf">
        <main jar="jrst-0.8.1.jar" />
        <lib>
            <fileset dir="${pathToJars}">
                <include name="batik-util-1.6-1.jar" />
                <include name="icu4j-2.6.1.jar" />
                <include name="commons-collections-3.1.jar" />
                <!-- Snip -->
            </fileset>
        </lib>
    </one-jar>
</target>
Ashley Mercer
quelle
1
Die Skriptfähigkeit von One-Jar mit Ant macht es in Continuous-Build-Systemen verwendbar.
Thorbjørn Ravn Andersen
1. Ist One-JAR in der Lage, wenn sich in meinem Glas mehrere Anwendungen (mehrere Einstiegspunktklassen) befinden? 2. Was ist, wenn dieses Glas von einer anderen Anwendung verwendet wird? Kann es auch die Klassen in verschachtelten Gläsern innerhalb des "One-JAR" verwenden?
MRalwasser
14

Wenn Sie ein Maven- Benutzer sind, macht das Assembly-Plugin normalerweise das, was Sie wollen, oder möglicherweise das Shadow-Plugin und in einigen Fällen eine Kombination.

Mit dem Assembly-Plugin fügen Sie eine Manifestdatei mit allen erforderlichen Einstellungen in Ihr Projekt ein, obwohl die Standardeinstellungen normalerweise recht gut sind. Der Bau ist dann erledigt mit

mvn assembly:assembly

Oder wenn Sie etwas Besonderes zu erledigen haben, eines der anderen Ziele. Alle einzuschließenden JAR-Dateien werden vom Abhängigkeitsauflöser von Maven erfasst. Wenn Sie das Schatten-Plugin verwenden, ist es normalerweise Teil des Installationsziels, und in einem bestimmten Projekt mache ich es jetzt

mvn install
mvn assembly:single

Das assembly:singleZiel ist es Lebensdauer Probleme zu umgehen, in diesem Fall in einem Frühling Anwendung.

larsivi
quelle
8

Sie können JarJar verwenden, das Paket-Shadowing verwendet, um sicherzustellen, dass Ihre JAR-Datei nicht mit anderen in Konflikt steht.

Steve g
quelle
8

Es gibt ProGuard, das nicht nur Ihre JAR-Dateien in eine packt, sondern auch Ihre Klassendateien optimieren, bereinigen oder verschleiern kann, wodurch die resultierende JAR-Datei viel kleiner wird als die Summe aller vorherigen JAR-Dateien.

Ich habe ProGuard tatsächlich mit dem JRST-Tool ausprobiert, und es ist, wie Sie berichtet haben. Ich habe versucht, das Problem aufzuspüren, und festgestellt, dass es sich um einen Fehler in der ICU4J-Bibliothek handelt, auf den jrst verweist. Das Problem ist, dass die verwendete ICU-Version derzeit weit veraltet ist. Also habe ich die icu.jarDatei durch ICU4J Version 3.2 ersetzt. Jetzt findet ProGuard eine Reihe weiterer Fehler / Warnungen bezüglich Inkonsistenzen mit den Bibliotheken von JRST.

Ich vermute, dass ProGuard wie erwartet funktioniert, aber die Bibliotheken von jrst sind einfach nicht konsistent. Ich weiß nicht, ob Sie viel mehr tun können, als mit den Entwicklern zu sprechen, da sie die Abhängigkeiten des Projekts überprüfen und aktualisieren sollten.

jrudolph
quelle
Vielen Dank! Ich habe es heruntergeladen und versucht, aber in diesem speziellen Feld bombardierte es mit unbekanntem konstantem Feld auf icu4j-2.6.1.jar,
tovare
7

(basierend auf Andrians):

<jar id="files" jarfile="all.jar">
  <zipgroupfileset dir="${library.dir}" includes="*.jar" excludes="test-helper.jar"/>
  <zipfileset src="first.jar" includes="**/*.java **/*.class"/>
  <zipfileset src="second.jar" includes="**/*.java **/*.class"/>
  <fileset dir=".">
    <include name="LICENSE"/>
    <include name="NOTICE"/>
  </fileset>
</jar>
象 嘉 道
quelle
5

One-JAR 0.97 wurde gerade unter http://one-jar.sourceforge.net veröffentlicht und durch die Unterstützung von Frameworks wie Spring und Guice erweitert , die andere Ansätze möglicherweise stören. Es behandelt auch die Classloader-Inversion, bei der sich einige JAR-Dateien außerhalb der One-JAR befinden (z. B. JDBC- Treiber, die möglicherweise nicht im Lieferumfang enthalten sind).

One-JAR ist eine Befehlszeile mit Ant- und Maven 2-Plugins. Es ist auch einfach, nur mit dem "jar" -Tool zu erstellen.

Ich kann auch den Eclipse Jar Exporter (Runnable) empfehlen, über den Ference Hechler geschrieben hat: Er hat großartige Arbeit geleistet, um einen einfachen Ansatz für das Umschließen einer Reihe von JAR-Dateien zu finden. Er und ich haben an One-JAR gearbeitet, aber der Jar Exporter basiert auf einer anderen Codebasis.

Simontuffs
quelle
3

Es gibt ein Tool namens autojar, das Ihren Bytecode scannt und eine JAR-Datei mit den gefundenen Klassen kompiliert, einschließlich referenzierter (importierter) Klassen.

Funktioniert jedoch nicht immer mit etwas wie Spring, bei dem Sie die Klassennamen in der Konfiguration angeben und es vom Framework geladen wird.


quelle
Vielen Dank für den Hinweis, es scheint, dass einige .jars in dieser speziellen Anwendung mir Kopfschmerzen bereiten, wenn ich das erledige.
tovare
3

Oder verwenden Sie das Maven Assembly Plugin (MVN Assembly: Assembly).

Philip Helger
quelle
2

Ich denke, dass das Tool, das Sie hier benötigen, JarSplice ist : http://ninjacave.com/jarsplice

Es erfordert weder Ant noch Maven, hat eine eigene GUI, es ist unkompliziert zu verwenden und genau das zu tun, was Sie gefragt haben -> Es führt den Inhalt mehrerer JAR-Dateien zu einer einzigen zusammen (bitte beachten Sie, dass noch ein eigener Klassenlader hinzugefügt werden muss ).

Nadir
quelle