2010-03-08 171 views
7

关于Ant和Eclipse有很多讨论,但以前没有回答似乎可以帮助我。如何从Ant构建文件设置Eclipse构建路径和类路径?

这里的交易:我试图构建与蚂蚁在命令行编译成功的Java程序。 (为了进一步混淆事项,我试图编译的程序是Ant本身。)

我真正想要做的就是将此项目引入Eclipse并在Eclipse中进行编译,使得类型绑定和变量绑定(来自Eclipse JDT的命名法)正确解析。我需要这个,因为我需要对构建在Eclipse JDT之上的代码运行静态分析。将Eclipse项目引入到Eclipse中的正常方式是Eclipse将构建它并解决所有绑定,只需将源目录导入到Java项目中,然后告诉它使用src/main /目录作为“源目录“。

不幸的是,这样做,用Ant使构建失败,无数的编译错误。在我看来,Ant构建文件正在设置类路径并正确构建路径(可能通过排除某些源文件),而Eclipse没有这些信息。

有什么办法可以将类路径&构建路径信息嵌入到Ant构建文件中,并将该信息提供给Eclipse放入其.project和.classpath文件中?我试过了,从现有的构建文件(文件菜单中的一个选项)创建一个新的项目,但这没有帮助。该项目仍然具有相同的编译错误。

感谢, 内尔斯

回答

6

我从来没有发现一个非常干净的方式做到这一点,但一“的hackish”的方式来做到这一点是操纵.classpath文件,Eclipse使用(这包含了构建路径) 。

所以的.classpath都将有东西在里面是这样的:

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

所以,你可以,例如,写某种批处理脚本,等这将读取你的Ant文件的依赖,并把他们进入eclipse .classpath文件(当然,格式正确)。

但就个人而言,我从来没有这样的事情糊弄。我要做的就是把所有的罐子我的项目需要一个文件夹中,然后在我的Ant文件我已经建立了这样的路径:

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

test_reflib只需无论这个文件夹是被定义为包含所有的罐子。

然后,在日食侧你可以做一个“添加罐子”,并导航到该相同的文件夹,并只挑选所有的罐子。更酷的是,只要在Eclipse文件夹中放入新的jar文件,只需点击eclipse项目的根目录下的“Refresh”,然后编辑构建路径并再次点击add jar,它将只显示jar文件您尚未添加到构建路径(即刚刚放入文件夹的新jar)。

如果你是在一个中心位置共享罐子这显然不工作也很好,但它的工作原理相当不错较小的项目,您可以在所有的罐子在刚刚复制到一个集中的文件夹中的项目。

+0

谢谢,这很有帮助。我很希望有人已经开发出你描述的那种脚本。特别是,这些构建文件有很多条件包含,我想自动解决它们。 – 2010-03-16 15:09:58

1

从原料蚁分布,第一下运行“ant -f fetch.xml”(或类似),以下载大量需要依赖。将这些添加到您的Eclipse项目中,看看它是否有帮助。

+0

这并不是我正在寻找的答案,但它非常有帮助,谢谢。 – 2010-03-16 15:05:12

1

我们已经产生的Eclipse的.classpath和.project文件从蚂蚁与位于中央的罐子(100+)(不包括SRC罐子和Javadoc)一个大项目。与从here链接的build.xml类似,显然增加了src和javadoc属性。

6

我用常春藤来管理我的ANT类路径,我强烈建议学习它是如何工作的。

有一个eclipse plugin将管理来自相同的ivy.xml文件的日食类路径,ANT用它来定义它的依赖关系。

2

我写了一个Ant任务生成一个Eclipse .userlibraries文件。您可以导入生成的文件以在Eclipse中创建用户库。然后将此用户库用作构建路径的一部分。

使用任务添加到您的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> 

Ant任务。它需要ant.jar来运行和编译:

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); 
    } 
}