2010-03-08 37 views
7

Hay mucha discusión sobre Ant y Eclipse, pero ninguna respuesta anterior parece ayudarme.¿Cómo configuro la ruta de compilación y la ruta de clase de Eclipse desde un archivo de compilación Ant?

Aquí está el trato: Estoy tratando de construir un programa Java que compila con éxito con Ant desde la línea de comandos. (Para complicar aún más las cosas, el programa que estoy intentando compilar es Ant).

Lo que realmente quiero hacer es llevar este proyecto a Eclipse y compilarlo en Eclipse de modo que los enlaces de tipo y los enlaces variables (nomenclatura de Eclipse JDT) se resuelven correctamente. Lo necesito porque necesito ejecutar un análisis estático en el código que está construido sobre Eclipse JDT. La manera normal en que traigo un proyecto Java a Eclipse para que Eclipse lo construya y resuelva todas las vinculaciones es simplemente importar los directorios fuente a un proyecto Java y luego decirle que use el directorio src/main/como un "directorio fuente" "

Desafortunadamente, hacer eso con Ant hace que la compilación falle con numerosos errores de compilación. Me parece que el archivo de compilación Ant está configurando la ruta de clase y la ruta de compilación correctamente (posiblemente excluyendo ciertos archivos de origen) y Eclipse no tiene esta información.

¿Hay alguna manera de tomar la ruta de clase & información de ruta de compilación incrustada en un archivo de compilación Ant y darle esa información a Eclipse para ponerla en sus archivos .project y .classpath? Lo he intentado, creando un nuevo proyecto a partir de un archivo de compilación existente (una opción en el menú Archivo) pero esto no ayuda. El proyecto todavía tiene los mismos errores de compilación.

Gracias, Nels

Respuesta

6

nunca he encontrado una forma muy limpia para hacerlo, pero de una manera "hacker" de hacerlo es manipular los usos archivo .classpath Eclipse (este contiene la ruta de compilación) .

Así que la .classpath va a tener cosas en él así:

<classpathentry kind="lib" path="C:/jboss-4.2.3.GA/client/jboss-system-client.jar"/> 

por lo que podría, por ejemplo, escribir algún tipo de script por lotes, etc., que se leería sus dependencias de los archivos de hormigas y poner en el archivo eclipse .classpath (en el formato adecuado, por supuesto).

Pero personalmente, nunca engaño con tales cosas. Lo que hago es simplemente poner todos los frascos mis necesidades del proyecto en una carpeta, y luego en mi archivo de hormigas tengo un camino establecido así:

<path id="all_libs"> 
    <fileset dir="test_reflib"> 
     <include name="**/*.jar"/> 
    </fileset> 
</path> 

test_reflib sólo necesita ser definido a donde esta carpeta es que contiene todos los frascos

Luego, en el lado del eclipse puedes simplemente hacer un "Añadir tarros" y navegar a esta misma carpeta y simplemente escoger todos los tarros. Lo que es aún más genial es que cada vez que coloques frascos nuevos en esta carpeta, simplemente haz clic en el nivel raíz en el proyecto de eclipse y haz "Actualizar", luego edita la ruta de compilación y haz clic en agregar jar nuevamente y solo te mostrará los frascos que aún no ha agregado a la ruta de compilación (es decir, el nuevo jar que acaba de colocar en la carpeta).

Obviamente, esto no funciona demasiado bien si comparte tarros en un lugar central, pero funciona bastante bien para proyectos más pequeños donde puede simplemente copiar todos los tarros en una carpeta centralizada para el proyecto.

+0

Gracias, esto es útil. Estoy esperando que alguien ya haya desarrollado el tipo de script que describes. En particular, estos archivos de compilación tienen muchas inclusiones condicionales y me gustaría resolverlas automáticamente. –

1

De la distribución de hormigas crudas, primero ejecute "ant -f fetch.xml" (o similar) para descargar muchas de las dependencias necesarias. Añádalos a su proyecto de Eclipse y vea si esto ayuda.

+0

Esta no fue exactamente la respuesta que estaba buscando, pero fue bastante útil, gracias. –

1

Hemos generado archivos Eclipse .classpath y .project de Ant para un gran proyecto con tarros ubicados en el centro (más de 100) (sin contar src jar y javadocs). Similar al build.xml vinculado desde here con la obvia adición de los atributos src y javadoc.

6

Uso la hiedra para administrar mis classpaths de ANT, recomiendo aprender cómo funciona.

Hay un eclipse plugin que gestionará la ruta de clase eclipse desde el mismo archivo ivy.xml que ANT utiliza para definir sus dependencias.

2

Escribí una Tarea Ant que genera un archivo Eclipse .userlibraries. Puede importar el archivo generado para crear una biblioteca de usuario en Eclipse. Y luego use esta biblioteca de usuario como parte de su ruta de compilación.

Para utilizar la tarea de añadir esto a su archivo de generación Ant:

<target name="createEclipseUserLibraries" 
     description="Creates classpath and bootclasspatch that can be imported into Eclipse"> 
    <taskdef name="createEclipseUserLibraries" 
      classname="com.forumsys.tools.CreateEclipseUserLibraries" 
      classpathref="yourclasspathref"/> 
    <createEclipseUserLibraries classpathref="classpathref" bootclasspathref="bootclasspathref"/> 
</target> 

Hormiga de tareas. Requiere ant.jar para ejecutar y compilar:

import java.io.BufferedOutputStream; 
import java.io.File; 
import java.io.FileOutputStream; 
import java.io.IOException; 

import org.apache.tools.ant.BuildException; 
import org.apache.tools.ant.Project; 
import org.apache.tools.ant.Task; 
import org.apache.tools.ant.types.Path; 
import org.apache.tools.ant.types.Reference; 

/** 
* A custom tag to create a file the eclipse can import to setup a user libraries. 
* 
* Created: Mar 29, 2014 9:44:09 AM 
* 
* @author <a href="mailto:[email protected]">Javier S. López</a> 
* @version 1.0 
*/ 
public class CreateEclipseUserLibraries extends Task { 
    public static final String UTF8_ENCODING = "UTF-8"; 
    public static final String DEFAULT_BOOT_CLASSPATH_LIBRARY_NAME = "SYSTEM_LIBRARY"; 
    public static final String DEFAULT_CLASSPATH_LIBRARY_NAME = "LIBRARY"; 
    public static final String DEFAULT_DESTINATION = "Eclipse.userlibraries"; 
    private static final String INDENT = " "; 
    private Path _classpath; 
    private Path _bootClasspath; 
    private String _bootClasspathLibraryName = DEFAULT_BOOT_CLASSPATH_LIBRARY_NAME; 
    private String _classpathLibraryName = DEFAULT_CLASSPATH_LIBRARY_NAME; 
    private String _destination = DEFAULT_DESTINATION; 

    public void setClasspath(final Path classpath) { 
     if (_classpath == null) { 
      _classpath = classpath; 
     } else { 
      _classpath.append(classpath); 
     } 
    } 

    public void setClasspathRef(final Reference reference) { 
     if (_classpath == null) { 
      final Project antProject = getProject(); 
      _classpath = new Path(antProject); 
     } 
     _classpath.setRefid(reference); 
    } 

    public void setBootClasspath(final Path bootClasspath) { 
     if (_bootClasspath == null) { 
      _bootClasspath = bootClasspath; 
     } else { 
      _bootClasspath.append(bootClasspath); 
     } 
    } 

    public void setBootClasspathRef(final Reference reference) { 
     if (_bootClasspath == null) { 
      final Project antProject = getProject(); 
      _bootClasspath = new Path(antProject); 
     } 
     _bootClasspath.setRefid(reference); 
    } 

    public void setClasspathLibraryName(final String name) { 
     if (!isEmpty(name)) { 
      _classpathLibraryName = name; 
     } 
    } 

    public void setBootClasspathLibraryName(final String name) { 
     if (!isEmpty(name)) { 
      _bootClasspathLibraryName = name; 
     } 
    } 

    public void setDestination(final String argDestination) { 
     if (!isEmpty(argDestination)) { 
      _destination = argDestination; 
     } 
    } 

    @Override 
    public void execute() throws BuildException { 
     if (_classpath == null) { 
      throw new BuildException("classpath or classpathref attribute must be set"); 
     } 

     if (_bootClasspath == null) { 
      throw new BuildException("bootclasspath or bootclasspathref attribute must be set"); 
     } 
     try { 
      createUserLibrariesFile(); 
     } catch (final IOException e) { 
      throw new BuildException(e.getMessage(), e); 
     } 
    } 

    /** 
    * @throws IOException 
    * 
    */ 
    private void createUserLibrariesFile() throws IOException { 
     final StringBuilder stringBuilder = new StringBuilder(); 
     stringBuilder.append("<?final xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>"); 
     stringBuilder.append("\n"); 
     stringBuilder.append("<eclipse-userlibraries version=\"2\">").append("\n"); 
     createBootClasspathLibrary(stringBuilder); 
     createClasspathLibrary(stringBuilder); 
     stringBuilder.append("</eclipse-userlibraries>"); 

     final Project antProject = getProject(); 
     final File baseDir = antProject.getBaseDir(); 
     final File file = new File(baseDir, _destination); 
     if (file.exists()) { 
      file.delete(); 
     } 
     final boolean append = false; 
     BufferedOutputStream bos = null; 
     try { 
      final FileOutputStream fos = new FileOutputStream(file, append); 
      bos = new BufferedOutputStream(fos); 
      bos.write(stringBuilder.toString().getBytes(UTF8_ENCODING)); 
      bos.flush(); 
     } finally { 
      if (bos != null) { 
       bos.close(); 
      } 
     } 
    } 

    /** 
    * @param stringBuilder 
    * 
    */ 
    private void createBootClasspathLibrary(final StringBuilder stringBuilder) { 
     createLibrary(stringBuilder, _bootClasspathLibraryName, true, _bootClasspath); 
    } 

    /** 
    * @param stringBuilder 
    */ 
    private void createClasspathLibrary(final StringBuilder stringBuilder) { 
     createLibrary(stringBuilder, _classpathLibraryName, false, _classpath); 
    } 

    /** 
    * @param stringBuilder 
    * @param bootClasspathLibraryName 
    * @param b 
    * @param bootClasspath 
    */ 
    private void createLibrary(final StringBuilder stringBuilder, final String libraryName, 
     final boolean isSystemLibrary, final Path path) { 
     stringBuilder.append(INDENT).append("<library name=\"").append(libraryName); 
     stringBuilder.append("\" systemlibrary=\"").append(Boolean.toString(isSystemLibrary)).append("\">\n"); 
     final String[] paths = path.list(); 
     final Project antProject = getProject(); 
     final File baseDir = antProject.getBaseDir(); 
     final String baseDirName = baseDir.getName(); 

     for (final String strPath : paths) { 
      final int index = strPath.indexOf(baseDirName); 
      //Only include the relative path 
      if (index != -1) { 
       stringBuilder.append(INDENT).append(INDENT); 
       stringBuilder.append("<archive path=\"").append(
        strPath.substring(index - 1)).append("\"/>\n"); 
      } 
     } 

     stringBuilder.append(INDENT).append("</library>\n"); 
    } 

    public static final boolean isEmpty(final String str) { 
     return (str == null) || (str.length() == 0); 
    } 
} 
Cuestiones relacionadas