2009-05-13 12 views
35

Nel file di build di seguito, la destinazione jar fa riferimento alla proprietà jar.class.path per il percorso classe manifest. L'obiettivo di compilazione si riferisce a project.class.pathGenera percorso classe manifest da <classpath> in Ant

C'è una ridondanza qui, perché jar.class.path e project.class.path sono molto simili. Devono essere entrambi aggiornati quando vengono aggiunte le librerie, il che può essere un problema se l'elenco delle librerie diventa molto lungo. C'è un modo migliore? Qualsiasi soluzione deve essere multipiattaforma e utilizzare sempre percorsi relativi.

Modifica:
Dovrebbe generare il classpath JAR da un set di file e non viceversa, quindi è possibile utilizzare i caratteri jolly ad es. includere tutti i file JAR in una directory.

<?xml version="1.0"?> 
<project name="Higgins" default="jar" basedir="."> 

    <property name="jar.class.path" value="lib/forms-1.2.0.jar lib/BrowserLauncher.jar"/> 

    <path id="project.class.path"> 
     <pathelement location="build"/> 
     <fileset dir="lib"> 
     <include name="forms-1.2.0.jar"/> 
     <include name="BrowserLauncher.jar"/> 
     </fileset> 
    </path> 

    <target name="prepare"> 
     <mkdir dir="build"/> 
    </target> 

    <target name="compile" depends="prepare" description="Compile core sources"> 
     <javac srcdir="src" 
       includes="**" 
       destdir="build" 
       debug="true" 
       source="1.5"> 
      <classpath refid="project.class.path"/> 
     </javac> 
    </target> 

    <target name="jar" depends="compile" description="Generates executable jar file"> 
     <jar jarfile="higgins.jar"> 
      <manifest> 
       <attribute name="Main-Class" value="nl.helixsoft.higgins.Main"/> 
       <attribute name="Class-Path" value="${jar.class.path}"/> 
      </manifest> 
      <fileset dir="build" includes="**/*.class"/>    
      <fileset dir="src" includes="**/*.properties"/>   
     </jar> 
    </target> 

</project> 

risposta

41

Supponendo Ant 1.7 o superiore, è possibile utilizzare l'attività manifestclasspath.

<path id="dep.runtime"> 
    <fileset dir="./lib"> 
     <include name="**/*.jar" /> 
    </fileset> 
</path> 
<property name="dep_cp" value="${toString:dep.runtime}" /> 

<target name="default"> 
    <manifestclasspath property="manifest_cp" jarfile="myjar.jar"> 
     <classpath refid="dep.runtime" /> 
    </manifestclasspath> 
    <echo message="Build Classpath: ${dep_cp}" /> 
    <echo message="Manifest Classpath: ${manifest_cp}" /> 
</target> 
+1

Questo funziona, ma solo se non si hanno percorsi assoluti nel classpath. Ad esempio, se si sta utilizzando il pacchetto debian 'libhibernate3-java' che installa in'/usr/share/java/hibernate3.jar' e lo includi nel classpath, l'attività ant manifest manifesterà un errore. La soluzione di Qianjigui funziona comunque. – joscarsson

2

Se si desidera solo un sottotracciato comune condiviso tra due (o più) i percorsi, che è facile da fare:

<path id="lib.path> 
    <fileset dir="lib"> 
     <include name="forms-1.2.0.jar"/> 
     <include name="BrowserLauncher.jar"/> 
    </fileset> 
</path> 

<path id="project.class.path"> 
    <pathelement location="build"/> 
    <path refid="lib.path"/> 
</path> 

<property name="jar.class.path" refid="lib.path"/> 

EDIT Scusa, ho frainteso la questione. Prova questo:

<property name="jar.class.path" value="lib/forms-1.2.0.jar lib/BrowserLauncher.jar"/> 

<path id="project.class.path"> 
    <pathelement location="build"/> 
    <fileset dir="." includes="${jar.class.path}"/> 
</path> 
+0

No, non è corretto. In questo caso, il valore di jar.class.path è separato da due punti anziché da spazi e, cosa peggiore, utilizzerà i percorsi completi rendendolo inutilizzabile per il manifest jar. – amarillion

+0

Risposta modificata in risposta al commento. –

+0

Sì, funziona nell'esempio che ho dato. Ma mi piacerebbe davvero costruire il classpath jar da un set di file e non viceversa, quindi posso usare i caratteri jolly. – amarillion

1

È possibile utilizzare <pathconvert> per convertire un percorso (che può contenere un set di file) in una stringa pianura. È probabile che tu debba <eco> che stringa in un file, utilizzare uno <sostituire> o <replaceregexp> per tagliare i bit iniziali del percorso, poi finalmente utilizzare <loadfile> per caricare la stringa manipolato nella proprietà finale.

Implementazione lasciata come esercizio al lettore.

+0

Questo funziona. Ho usato questa soluzione nei miei script delle formiche ad un certo punto. Ma è disordinato. –

+0

Davvero disordinato. Mi piacerebbe davvero vedere un esempio funzionante di ciò che taglia i bit del percorso principale in un modo multipiattaforma ... – amarillion

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

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

<target depends="compile" name="buildjar"> 
    <jar jarfile="${basedir}/${test.jar}"> 
    <fileset dir="${build}" /> 
    <manifest> 
     <attribute name="Main-Class" value="com.mycompany.TestMain"/> 
     <attribute name="Class-Path" value="${manifest.classpath}"/> 
    </manifest> 
</jar> 
</target> 

Per ulteriori informazioni visitate this article.

+0

grazie, è stato molto utile! –

+0

Perché questa risposta non è accettata? Questo è perfetto e funziona anche con più convertitori di percorso – ha9u63ar

Problemi correlati