如何从Ant构建文件设置Eclipse构建路径和类路径?

时间:2010-03-08 19:48:21

标签: java eclipse ant build eclipse-jdt

关于Ant和Eclipse有很多讨论,但之前没有回答似乎对我有帮助。

这是交易:我正在尝试构建一个Java程序,它可以从命令行成功编译Ant。 (为了进一步混淆问题,我试图编译的程序是Ant本身。)

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

不幸的是,使用Ant执行此操作会导致构建失败并出现大量编译错误。在我看来,Ant构建文件正在设置类路径并正确构建路径(可能通过排除某些源文件),Eclipse没有这些信息。

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

谢谢, NELS

5 个答案:

答案 0 :(得分:6)

我从来没有找到一种非常干净的方法,但是一种“hackish”方法是操纵eclipse使用的.classpath文件(这包含构建路径)。

所以.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只需要定义到包含所有jar的文件夹。

然后,在日食方面你可以做一个“添加罐子”并导航到同一个文件夹,然后选择所有的罐子。甚至更酷的是,无论何时将新罐放入此文件夹,只需单击eclipse项目中的根级别并执行“刷新”,然后编辑构建路径并再次单击添加jar,它将仅显示罐子您还没有添加到构建路径(即刚刚放入文件夹中的新jar)。

如果你在一个中心位置共享罐子,这显然效果不好,但它适用于小型项目,你只需将所有罐子复制到项目的集中文件夹即可。

答案 1 :(得分:6)

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

有一个eclipse plugin将从同一个 ivy.xml 文件管理eclipse类路径,ANT用它来定义它的依赖项。

答案 2 :(得分:2)

我编写了一个生成Eclipse .userlibraries文件的Ant Task。您可以导入生成的文件以在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:jslopez@gmail.com">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);
    }
}

答案 3 :(得分:1)

从原始ant分发中,首先运行“ant -f fetch.xml”(或类似的)来下载许多所需的依赖项。将这些添加到Eclipse项目中,看看它是否有帮助。

答案 4 :(得分:1)

我们已经从Ant为一个大型项目生成了Eclipse .classpath和.project文件,这些文件位于中心位置的jar(100+)(不包括src jars和javadocs)。类似于从here链接的build.xml,显然添加了src和javadoc属性。