2009-05-13 15 views
35

En el siguiente archivo de compilación, el destino de jar se refiere a la propiedad jar.class.path para la clase-ruta de manifiesto. El objetivo de compilación se refiere a project.class.pathGenerar la ruta de clase de manifiesto desde <classpath> en Ant

Aquí hay redundancia, porque jar.class.path y project.class.path son muy similares. Deben actualizarse cuando se agregan bibliotecas, lo que puede ser complicado si la lista de bibliotecas es muy larga. ¿Hay una mejor manera? Cualquier solución debe ser multiplataforma y usar siempre rutas relativas.

Editar:
Debe generar el classpath JAR de un conjunto de archivos y no al revés, así que puedo usar comodines para, p. incluir todos los archivos JAR en un directorio.

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

Respuesta

41

Asumiendo Ant 1.7 o superior, puede usar la tarea 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

Esto funciona, pero solo si no tienes rutas absolutas en tu ruta de clase. Por ejemplo, si está utilizando el paquete Debian 'libhibernate3-java' que se instala en'/usr/share/java/hibernate3.jar' y lo incluye en su classpath, la tarea ant antiguedades classp lanzará un error. Sin embargo, la solución de Qianjigui aún funciona. – joscarsson

2

Si lo que desea es un subtrazado común compartido entre dos (o más) rutas, es fácil de hacer:

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

EDITAR Lo sentimos, no he entendido bien la pregunta. Prueba esto:

<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, eso es incorrecto. En este caso, el valor de jar.class.path está separado por dos puntos en lugar de espacios, y lo que es peor, utilizará rutas completas, lo que lo hace inútil para el manifiesto de jar. – amarillion

+0

Respuesta editada en respuesta al comentario. –

+0

Sí, eso funciona en el ejemplo que di. Pero realmente me gustaría construir el classpath de jar desde un conjunto de archivos y no al revés, para poder usar comodines. – amarillion

1

Usted puede utilizar <pathconvert> para convertir un camino (que puede contener un conjunto de archivos) en una cadena sin formato. Es probable que necesite <eco> esa cadena a un archivo, siga cualquiera <reemplazar> o <replaceregexp> para cortar los bits iniciales de ruta, y finalmente utilizar <loadfile> para cargar la cadena de manipulado en la propiedad final.

Implementación dejada como un ejercicio para el lector.

+0

Esto funciona. Usé esta solución en mis scripts de hormigas en algún momento. Pero es desordenado. –

+0

Desordenado de hecho. Realmente me gustaría ver un ejemplo de esto que corte los bits de la ruta principal de forma multiplataforma ... – 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> 

Para más información, visite this article.

+0

¡gracias esto ha sido muy útil! –

+0

¿Por qué no se acepta esta respuesta? Esto es perfecto y funciona incluso con múltiples convertidores de ruta – ha9u63ar

Cuestiones relacionadas