2009-11-30 2 views
57

Sto usando Ant per creare alcuni progetti Java.
In alcuni, ho una directory lib/, che contiene dipendenze esterne, nel modulo su file JAR.Creazione di un contenitore di bundle con formica

Durante la compilazione, creo un jar in bundle, che contiene il codice del progetto, insieme alle dipendenze, aggiungendo al file jar bundle uno zipfileset per ciascuno dei jar nella directory lib/.

Il problema è, che ogni volta che aggiungere un barattolo, o cambiare nomi, ho bisogno di ricordarsi di aggiornare il file build.xml, come non ho potuto trovare un modo per l'aggiunta di quelli zipfilesets in modo automatico che includerà tutti vasi in un certo schema (ad es. lib/*.jar).

C'è un modo migliore per farlo?

Ho pensato di scrivere il mio compito Ant per questo, o usando l'API di form di Groovy per farlo a livello di codice, ma mi chiedevo se c'è un modo per farlo usando il form "vanilla".

risposta

50

Nel mio obiettivo, ho qualcosa di simile:

<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> 

Ed ecco come lo costruire il mio percorso di classe:

<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 viene utilizzato dal target pacchetto inviato sopra. Questa parte l'ho copiata da qualche altra parte, quindi non mi è molto familiare.

Modifica rapida. Javac ha bisogno di conoscere anche questi barattoli.

<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

Ecco un metodo simile a quello di jonescb che contiene l'ultimo 'build.xml' (la grande immagine) che manca in questa risposta: http://www.mkyong.com/ant/ant-create-a-fat-jar -file/ – Stephan

0

Ecco un semplice esempio di un obiettivo di formica che creerà un jar (denominato test.jar) che include tutti i file jar nella directory lib. Forse questo risolverà il tuo problema?

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

I file jar possono essere semplicemente nidificati? Sei sicuro che funzionerà? – abyx

+0

hmmm, immagino di no, stavo pensando guerre e webapps invece di barattoli, mi dispiace per quello. – Upgradingdave

29

Utilizzare uno zipgroupfileset. Ad esempio:

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

Il zipgroupfileset è documentato il compito Zip.

+0

Come ha risposto jonescb, questa è davvero la soluzione. Mai visto, poiché è nascosto nell'attività Zip – abyx

+0

Il grosso problema con questo è se i file jar hanno file extra, in genere nella directory MANIFEST. Per esempio, molti dei vasetti della struttura della molla contengono spring.handlers, spring.schemas e spring.tooling che ... beh, non ho capito come gestirli .. unire? – ticktock

+1

@GeorgeBaxter State cercando la stessa cosa e ho finito col fare [questo] (http://stackoverflow.com/a/24083318/2208271). Fammi sapere se trovi una soluzione migliore. – Sithsu

6

Per quelli di voi che usano NetBeans ecco come è possibile creare archivio JAR con le librerie in bundle con zipgroupfileset:

<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> 

Ho aggiunto questa definizione bersaglio fino alla fine del file build.xml. Il nome del target è -post-jar.