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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2404224/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 07:06:59  来源:igfitidea点击:

How do I set the Eclipse build path and class path from an Ant build file?

javaeclipseantbuildeclipse-jdt

提问by Nels Beckman

There's a lot of discussion about Ant and Eclipse, but no previously answered seems to help me.

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

Here's the deal: I am trying to build a Java program that compiles successfully with Ant from the command-line. (To confuse matters further, the program I am attempting to compile is Ant itself.)

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

What I really want to do is to bring this project into Eclipse and have it compile in Eclipse such that the type bindings and variable bindings (nomenclature from Eclipse JDT) are correctly resolved. I need this because I need to run a static analysis on the code that is built on top of Eclipse JDT. The normal way I bring a Java project into Eclipse so that Eclipse will build it and resolve all the bindings is to just import the source directories into a Java project, and then tell it to use the src/main/ directory as a "source directory."

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

Unfortunately, doing that with Ant causes the build to fail with numerous compile errors. It seems to me that the Ant build file is setting up the class path and build path correctly (possibly by excluding certain source files) and Eclipse does not have this information.

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

Is there any way to take the class path & build path information embedded in an Ant build file, and given that information to Eclipse to put in its .project and .classpath files? I've tried, creating a new project from an existing build file (an option in the File menu) but this does not help. The project still has the same compile errors.

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

Thanks, Nels

谢谢,尼尔斯

回答by dcp

I've never found a really clean way to do it, but one "hackish" way to do it is to manipulate the .classpath file eclipse uses (this contains the build path).

我从来没有找到一种真正干净的方法来做到这一点,但一种“hackish”的方法是操作 .classpath 文件 eclipse 使用(其中包含构建路径)。

So the .classpath is going to have stuff in it like this:

所以 .classpath 里面会有这样的东西:

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

So you could, for example, write some sort of batch script, etc. which would read your ant file dependencies and put them into the eclipse .classpath file (in the proper format, of course).

因此,例如,您可以编写某种批处理脚本等,这些脚本会读取您的 ant 文件依赖项并将它们放入 eclipse .classpath 文件中(当然,以正确的格式)。

But personally, I never fool with such things. What I do is just put all the jars my project needs in one folder, and then in my ant file I have a path set up like this:

但就我个人而言,我从不愚弄这些事情。我所做的只是将我的项目需要的所有 jars 放在一个文件夹中,然后在我的 ant 文件中我有一个这样设置的路径:

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

test_reflib just needs to be defined to wherever this folder is that contains all the jars.

test_reflib 只需要定义为包含所有 jar 的文件夹所在的位置。

Then, on the eclipse side you can just do a "Add jars" and navigate to this same folder and just pick all the jars. What's even cooler is that any time you drop new jars into this folder, just click at the root level in the eclipse project and do "Refresh", and then edit the build path and click add jar again and it will only show you the jars that you haven't already added to the build path yet (i.e. the new jar you just dropped into the folder).

然后,在 Eclipse 方面,您只需执行“添加 jars”并导航到同一个文件夹并选择所有 jars。更酷的是,每当您将新 jar 放入此文件夹时,只需单击 eclipse 项目的根级别并执行“刷新”,然后编辑构建路径并再次单击添加 jar,它只会向您显示 jar您尚未添加到构建路径中的(即您刚刚放入文件夹中的新 jar)。

This obviously doesn't work too well if you are sharing jars in a central place, but it works pretty well for smaller projects where you can just copy all the jars over to a centralized folder for the project.

如果您在中央位置共享 jar,这显然不太好用,但是对于较小的项目,您可以将所有 jar 复制到项目的集中文件夹中,这对于较小的项目来说效果很好。

回答by Thorbj?rn Ravn Andersen

From the raw ant distribution, first run "ant -f fetch.xml" (or similar) to download a lot of needed dependencies. Add these to your Eclipse project and see if it helps.

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

回答by EGHM

We have generated Eclipse .classpath and .project files from Ant for a large project with centrally located jars (100+) (not counting src jars and javadocs). Similar to the build.xml linked from herewith the obvious addition of the src and javadoc attributes.

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

回答by Mark O'Connor

I use the ivy to manage my ANT classpaths, I highly recommend learning how it works.

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

There is an eclipse pluginthat will manage the eclipse classpath from the same ivy.xmlfile that ANT uses to define it's dependencies.

有一个eclipse 插件可以从ANT 用来定义它的依赖项的同一个ivy.xml文件中管理 eclipse 类路径。

回答by Javier S López

I wrote an Ant Task that generates an Eclipse .userlibraries file. You can import the generated file to create a user library in Eclipse. And then use this user library as part of your build path.

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

To use the task add this to your ant build file:

要使用该任务,请将其添加到您的 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 Task. It requires ant.jar to run and compile:

蚂蚁任务。它需要 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);
    }
}