2009-11-30 2 views
57

Ich verwende Ant, um einige Java-Projekte zu erstellen.
In einigen habe ich ein lib/ Verzeichnis, das externe Abhängigkeiten enthält, in Form von JAR-Dateien.Erstellen eines Bündelglas mit Ant

Während des Build, erstelle ich eine gebündelte Glas, dass das Projekt den Code enthält, neben den Abhängigkeiten, indem zu dem Bündel jar einen zipfileset für jedes der Gläser in den lib/ Verzeichnis einreichen.

Das Problem ist, dass jedes Mal, wenn ich ein Glas hinzufügen oder Namen ändern, muss ich daran denken, die build.xml Datei zu aktualisieren, da ich keinen Weg finden konnte, diese in einer automatischen Weise, die alle enthalten Gläser in einem bestimmten Muster (zB lib/*.jar).

Gibt es einen besseren Weg, dies zu tun?

Ich habe überlegt, meine eigene Ant-Aufgabe dafür zu schreiben oder Groovys Ameisen-API zu verwenden, um das programmatisch zu machen, aber ich fragte mich, ob es eine Möglichkeit gibt, dies mit "vanilla" ant zu tun.

Antwort

50

In meinem Ziel, ich habe so etwas wie dies:

<jar destfile="${store.dir}/temp_final.jar" filesetmanifest="skip"> 
    <zipgroupfileset dir="dist" includes="*.jar"/> 
    <zipgroupfileset dir="dist/lib" includes="*.jar" excludes=""/> 

    <manifest> 
     <attribute name="Main-Class" value="${main.class}"/> 
     <attribute name="Class-Path" value="${mf.classpath}"/> 
    </manifest> 
</jar> 

Und hier ist, wie ich meine Classpath bauen:

<path id="build.classpath"> 
    <fileset dir="${basedir}/"> 
     <include name="${lib.dir}/*.jar"/> 
    </fileset> 
</path> 

<pathconvert property="mf.classpath" pathsep=" "> 
    <path refid="build.classpath"/> 
    <mapper> 
     <chainedmapper> 
      <flattenmapper/> 
      <globmapper from="*.jar" to="lib/*.jar"/> 
     </chainedmapper> 
    </mapper> 
</pathconvert> 

mf.classpath aus dem Paket Ziel verwendet wird geschrieben über. Dieser Teil habe ich von woanders kopiert, daher kenne ich ihn nicht so gut.

Schnellbearbeitung. Javac muss auch über diese Gläser Bescheid wissen.

<path id="jars"> 
    <fileset dir="${lib.dir}" includes="**/*.jar"/> 
</path> 

<target name="compile"> 
    <mkdir dir="${build.dir}"/> 
    <javac srcdir="${src.dir}" destdir="${build.dir}" classpathref="jars" debug="on"/> 
</target> 
+1

Hier ist eine ähnliche Methode wie die von jonescb, die das letzte 'build.xml' (das große Bild) enthält, das in dieser Antwort fehlt: http://www.mkyong.com/ant/ant-create-a-fat-jar -file/ – Stephan

0

Hier ist ein einfaches Beispiel für ein ant-Ziel, das ein jar (namens test.jar) erstellt, das alle jar-Dateien im Verzeichnis lib enthält. Vielleicht wird das dein Problem lösen?

<target name="jar"> 
    <jar destfile="test.jar"> 
     <fileset dir="lib/" includes="**/*.jar" /> 
    </jar> 
</target> 
+1

Können JAR-Dateien einfach verschachtelt werden? Sind Sie sicher, dass das funktioniert? – abyx

+0

hmmm, ich glaube nicht, ich dachte an Kriege und Webapps anstelle von Gläsern, tut mir leid. – Upgradingdave

29

Verwenden Sie eine zipgroupfileset. Zum Beispiel:

<target name="jar"> 
    <jar destfile="foo.jar" basedir="${dir.classes}"> 
     <zipgroupfileset dir="lib" includes="*.jar"/> 
    </jar> 
</target> 

Die zipgroupfileset mit der Zip Aufgabe dokumentiert.

+0

Wie jonescb antwortete, ist das wirklich die Lösung. Nie gesehen, wie es in der Zip-Task – abyx

+0

versteckt ist Das große Problem dabei ist, wenn die JAR-Dateien zusätzliche Dateien haben, in der Regel im MANIFEST-Verzeichnis. Zum Beispiel, viele der Frühling Rahmen Gläser enthalten spring.handlers, spring.schemas und spring.tooling Dateien, die .. nun, ich habe nicht gedacht, wie mit diesen umzugehen .. Zusammenführung? – ticktock

+1

@GeorgeBaxter Ich war auf der Suche nach der gleichen Sache und endete damit [dies] (http://stackoverflow.com/a/24083318/2208271). Lassen Sie es mich wissen, wenn Sie eine bessere Lösung finden. – Sithsu

6

Für die von Ihnen NetBeans hier verwendet, ist, wie Sie JAR-Archiv mit Bibliotheken gebündelte mit zipgroupfileset erstellen:

<target name="-post-jar"> 

    <property name="store.jar.name" value="MyJarName"/> 

    <property name="store.dir" value="dist"/> 
    <property name="store.jar" value="${store.dir}/${store.jar.name}.jar"/> 

    <echo message="Packaging ${application.title} into a single JAR at ${store.jar}"/> 

    <jar destfile="${store.dir}/temp_final.jar" filesetmanifest="skip"> 
     <zipgroupfileset dir="dist" includes="*.jar"/> 
     <zipgroupfileset dir="dist/lib" includes="*.jar"/> 

     <manifest> 
      <attribute name="Main-Class" value="${main.class}"/> 
     </manifest> 
    </jar> 

    <zip destfile="${store.jar}"> 
     <zipfileset src="${store.dir}/temp_final.jar" 
     excludes="META-INF/*.SF, META-INF/*.DSA, META-INF/*.RSA"/> 
    </zip> 

    <delete file="${store.dir}/temp_final.jar"/> 
    <delete dir="${store.dir}/lib"/> 
    <delete file="${store.dir}/README.TXT"/> 
</target> 

Ich habe hinzugefügt, um diese Zieldefinition bis zum Ende der Datei build.xml. Zielname ist -post-jar.