Externe JAR-Dateien in eine neue JAR-Datei einfügen, die mit Ant erstellt wurde
Gerade habe ich 'geerbt' ein Java-Projekt und kommen nicht aus einem Java-hintergrund, ich bin ein wenig verloren manchmal. Eclipse Debuggen und ausführen der Anwendung während der Entwicklung. Ich habe über Eclipse gelungen ist ein .jar-Datei 'includes' werden alle erforderlichen externen jars wie Log4J, xmlrpc-server, etc. Dieses große .jar kann dann erfolgreich ausgeführt werden mit:
java -jar myjar.jar
Mein Nächster Schritt ist zum automatisieren von builds mit Ant - (version 1.7.1), damit ich nicht mit Eclipse zu tun-builds und-Bereitstellung. Dies hat sich als eine Herausforderung aufgrund meiner mangelnden java-Kenntnissen. Die Wurzel des Projekts sieht wie folgt aus:
|-> jars (where external jars have been placed)
|-> java
| |-> bin (where the finished .class / .jars are placed)
| |-> src (Where code lives)
| |-> ++files like build.xml etc
|-> sql (you guessed it; sql! )
Meine build.xml enthält die folgenden:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project basedir="." default="build" name="Seraph">
<property environment="env"/>
<property name="debuglevel" value="source,lines,vars"/>
<property name="target" value="1.6"/>
<property name="source" value="1.6"/>
<property name="build.dir" value="bin"/>
<property name="src.dir" value="src"/>
<property name="lib.dir" value="../jars"/>
<property name="classes.dir" value="${build.dir}/classes"/>
<property name="jar.dir" value="${build.dir}/jar"/>
<property name="jar.file" value="${jar.dir}/seraph.jar"/>
<property name="manifest.file" value="${jar.dir}/MANIFEST.MF"/>
<property name="main.class" value="no.easyconnect.seraph.core.SeraphCore"/>
<path id="external.jars">
<fileset dir="${lib.dir}" includes="**/*.jar"/>
</path>
<path id="project.classpath">
<pathelement location="${src.dir}"/>
<path refid="external.jars" />
</path>
<target name="init">
<mkdir dir="${build.dir}"/>
<mkdir dir="${classes.dir}"/>
<mkdir dir="${jar.dir}"/>
<copy includeemptydirs="false" todir="${build.dir}">
<fileset dir="${src.dir}">
<exclude name="**/*.launch"/>
<exclude name="**/*.java"/>
</fileset>
</copy>
</target>
<target name="clean">
<delete dir="${build.dir}"/>
</target>
<target name="cleanall" depends="clean"/>
<target name="build" depends="init">
<echo message="${ant.project.name}: ${ant.file}"/>
<javac debug="true" debuglevel="${debuglevel}" destdir="bin" source="${source}" target="${target}" classpathref="project.classpath">
<src path="${src.dir}"/>
</javac>
</target>
<target name="build-jar" depends="build">
<delete file="${jar.file}" />
<delete file="${manifest.file}" />
<manifest file="${manifest.file}" >
<attribute name="built-by" value="${user.name}" />
<attribute name="Main-Class" value="${main.class}" />
</manifest>
<jar destfile="${jar.file}"
basedir="${build.dir}"
manifest="${manifest.file}">
<fileset dir="${classes.dir}" includes="**/*.class" />
<fileset dir="${lib.dir}" includes="**/*.jar" />
</jar>
</target>
</project>
Ich dann ausführen:
ant clean build-jar
und eine Datei namens seraph.jar ist in den java/bin/jar-Verzeichnis. Ich versuche dann zu laufen, diese jar-Datei mit dem folgenden Befehl:
java-jar bin/jar/seraph.jar
Das Ergebnis ist diese Ausgabe auf der Konsole:
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/log4j/Logger
at no.easyconnect.seraph.core.SeraphCore.<clinit>(SeraphCore.java:23)
Caused by: java.lang.ClassNotFoundException: org.apache.log4j.Logger
at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
... 1 more
Could not find the main class: no.easyconnect.seraph.core.SeraphCore. Program will exit.
Vermute ich, dass ich etwas getan haben, unglaublich dumm in dem build.xml-Datei und verbrachte den besseren Teil von zwei Tagen versuchen Variationen der Konfiguration, leider ohne Erfolg. Jede Hilfe zu bekommen, diese Arbeit wird sehr geschätzt.
Oh, und tut mir Leid wenn ich einige wichtige Informationen mit. Dies ist meine erste mal hier in SO.
InformationsquelleAutor der Frage Christopher | 2010-09-22
Du musst angemeldet sein, um einen Kommentar abzugeben.
Aus ant buildfile, ich gehe davon aus, dass das, was Sie wollen, ist zu einem einzigen JAR-Archiv, enthält nicht nur Ihrer Anwendung Klassen, aber auch den Inhalt der anderen Gläser in Ihrer Anwendung.
Jedoch Ihre
build-jar
Datei ist gerade dabei erforderlichen Gläser in deiner eigenen JAR; das wird nicht funktionieren, wie beschrieben hier (siehe Hinweis).Versuchen, dies zu ändern:
:
Mehr flexible und leistungsfähige Lösungen sind die JarJar oder One-Jar Projekte. Einen Blick in diese, wenn die oben nicht erfüllen Ihre Anforderungen.
InformationsquelleAutor der Antwort Grodriguez
Mit den hilfreichen Ratschläge von Leuten, die hier beantwortet ich begann zu Graben in One-Jar. Nach einigen Sackgassen (und einige Ergebnisse, die, genau wie meine bisherigen Ergebnisse habe ich es geschafft es zum laufen zu bringen. Für andere Völker Referenz Liste ich die build.xml das funktionierte für mich.
Ich hoffe, jemand anders kann davon profitieren.
InformationsquelleAutor der Antwort Christopher
Cheesle richtig ist. Es gibt keine Möglichkeit für den classloader zu finden, die eingebettete jars. Wenn man genügend debug-Befehle auf der Befehlszeile, die Sie sollten in der Lage sein zu sehen, die "java" - Befehl, andernfalls Stell die Gläser auf ein classpath
Was Sie wollen, ist manchmal ein so genanntes "uberjar'. Ich fand one-jar als Werkzeug, um aus Ihnen machen, aber ich habe es nicht ausprobiert. Sicher, es gibt viele andere Ansätze.
InformationsquelleAutor der Antwort Julian Simpson
Zwei Möglichkeiten, entweder auf den neuen jars in den classpath oder entpacken Sie alle Klassen in der umschließenden Gefäße und re-jar die ganze Menge! Soweit ich weiß Verpackung jars innerhalb von jars ist nicht recommeneded und du wirst immer die Klasse nicht gefunden Ausnahme!
InformationsquelleAutor der Antwort Cheesle
Als Cheesle sagte, Sie Auspacken können und Ihre Bibliothek Gläser und re-jar Sie alle mit der folgenden Modifikation.
Jar-Dateien sind einfach nur zip-Dateien mit einem manifest-Datei eingebettet. Sie können extrahieren und neu packen die Abhängigkeit Gläser in Ihrer Anwendung-Jar-Datei.
http://ant.apache.org/manual/Tasks/zip.html
"Die Zip-Aufgabe unterstützt auch die Zusammenführung mehrerer zip Dateien in die zip-Datei. Dies ist möglich entweder durch das src-Attribut des verschachtelte Dateigruppen oder durch die Verwendung der speziellen verschachteltes fileset zipgroupfileset."
Tun, achten Sie auf die Lizenzen beteiligt, die mit Ihrer Abhängigkeit libaries. Verlinken extern auf die Bibliothek und darunter die Bibliothek in Ihrer Anwendung sind sehr verschiedene Dinge rechtlich.
EDIT 1: Verdammt mein langsames Tippen. Grodriguez mich zu schlagen. 🙂
EDIT 2: Wenn Sie sich entscheiden, Sie können nicht zählen Ihre Abhängigkeiten in die Anwendung, dann müssen Sie Sie in Ihre Jar - classpath entweder auf der Kommandozeile beim Start oder über die Manifest-Datei. Es gibt einen schönen Befehl ANT behandeln die speziellen Formatierung der classpath in der Manifest-Datei für Sie.
InformationsquelleAutor der Antwort Tansir1
Dies ist ein classpath-Problem beim ausführen eine ausführbare jar-Datei wie folgt:
Einen Weg, um das problem zu beheben ist, um den Klassenpfad für die java-Befehlszeile wie folgt, hinzufügen der fehlenden log4j jar:
Natürlich die beste Lösung ist, fügen Sie der classpath in der jar-manifest-so dass wir können das "-jar" java-option:
Folgende Antwort veranschaulicht, wie Sie mithilfe der manifestclasspath zu automatisieren, das seeting der manifest-classpath-Eintrag
Kann nicht finden, die Main-Klasse in Datei kompilieren Mit Ant
InformationsquelleAutor der Antwort Mark O'Connor
Ich bin mit NetBeans und brauchte eine Lösung für dieses auch. Nach googleling rund um und ausgehend von Christopher ' s Antwort habe ich es geschafft ein Skript erstellen, das Ihnen hilft, dies ganz einfach in NetBeans. Ich Stelle die Anleitung hier, falls jemand anderes Sie brauchen.
Was Sie tun müssen, ist download one-jar. Sie können über den link von hier: http://one-jar.sourceforge.net/index.php?page=getting-started&Datei=ant
Extrahieren Sie die jar-Archiv und suchen Sie nach one-jar\ "dist" - Ordner, der enthält eine-jar-ant-Aufgabe-.jar, one-jar-ant-task.xml und eine-jar-boot-.jar. Extrahieren oder kopieren Sie Sie auf einen Pfad, fügen wir dem Skript unten, als der Wert der Eigenschaft ein-Glas.dist.dir.
Nur kopieren Sie das folgende Skript am Ende Ihrer build.xml Skript (aus dem NetBeans-Projekt), nur vor - /Projekt-tag, ersetzen Sie den Wert für one-jar.dist.dir mit dem richtigen Pfad, und führen Sie eine-jar Ziel.
Für diejenigen von Euch, die nicht vertraut sind mit der Ausführung von Zielen, dieses tutorial könnte helfen: http://www.oracle.com/technetwork/articles/javase/index-139904.html . Es zeigt Ihnen auch, wie Sie Quellen in ein Glas, aber Sie sind explodiert, die nicht komprimiert in Gläser.
Beste von Glück und vergessen Sie nicht zu Stimmen, wenn es Ihnen geholfen hat.
InformationsquelleAutor der Antwort Alex Burdusel
Können Sie einen bit-Funktionalität, die bereits gebaut, um die ant jar task.
Wenn Sie gehen, um Die Dokumentation der ant jar task und nach unten scrollen, um die "Verschmelzung Archive" Abschnitt gibt es ein snippet für alle *.die class-Dateien aus allen Gläsern, die in Sie "lib/main" Verzeichnis:
Diese Erzeugt eine ausführbare jar-Datei mit einer main-Klasse "com.acme.checksites.Main", und bettet alle Klassen aus allen jar-Dateien in lib/main.
Nichts kluges im Fall der namespace-Konflikte, Duplikate und ähnliche Dinge. Auch wird es gehören alle class-Dateien, auch diejenigen, die Sie nicht verwenden, so dass die kombinierte jar-Datei in voller Größe.
Wenn du mehr brauchst fortgeschrittene Dinge wie, dass, werfen Sie einen Blick auf wie one-jar und jar jar links
InformationsquelleAutor der Antwort Sebastian Vilstrup