简体   繁体   English

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

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

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. 这是交易:我正在尝试构建一个Java程序,它可以从命令行成功编译Ant。 (To confuse matters further, the program I am attempting to compile is Ant itself.) (为了进一步混淆问题,我试图编译的程序是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. 我真正想要做的是将这个项目带入Eclipse并在Eclipse中编译,以便正确解析类型绑定和变量绑定(来自Eclipse JDT的命名法)。 I need this because I need to run a static analysis on the code that is built on top of Eclipse JDT. 我需要这个,因为我需要对构建在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." 我将Java项目引入Eclipse以便Eclipse构建并解析所有绑定的常规方法是将源目录导入Java项目,然后告诉它使用src / main /目录作为“源目录” “。

Unfortunately, doing that with Ant causes the build to fail with numerous compile errors. 不幸的是,使用Ant执行此操作会导致构建失败并出现大量编译错误。 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构建文件正在设置类路径并正确构建路径(可能通过排除某些源文件),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? 有没有办法获取嵌入在Ant构建文件中的类路径和构建路径信息,并将这些信息提供给Eclipse以放入其.project和.classpath文件中? 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. 该项目仍然具有相同的编译错误。

Thanks, Nels 谢谢,内尔斯

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”方法是操纵eclipse使用的.classpath文件(这包含构建路径)。

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: 我所做的只是将我的项目所需的所有罐子放在一个文件夹中,然后在我的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 (ie the new jar you just dropped into the folder). 甚至更酷的是,无论何时将新罐放入此文件夹,只需单击eclipse项目中的根级别并执行“刷新”,然后编辑构建路径并再次单击添加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. 如果你在一个中心位置共享罐子,这显然不会很好,但它适用于较小的项目,你可以将所有罐子复制到项目的集中文件夹。

I use the ivy to manage my ANT classpaths, I highly recommend learning how it works. 我使用常春藤管理我的ANT类路径,我强烈建议学习它是如何工作的。

There is an eclipse plugin that will manage the eclipse classpath from the same ivy.xml file that ANT uses to define it's dependencies. 有一个eclipse插件 ,它将从ANT用来定义它的依赖项的同一个ivy.xml文件中管理eclipse类路径。

I wrote an Ant Task that generates an Eclipse .userlibraries file. 我写了一个Ant任务,生成一个Eclipse .userlibraries文件。 You can import the generated file to create a user library in Eclipse. 您可以导入生成的文件以在Eclipse中创建用户库。 And then use this user library as part of your build path. 然后将此用户库用作构建路径的一部分。

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. Ant任务。 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: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);
    }
}

From the raw ant distribution, first run "ant -f fetch.xml" (or similar) to download a lot of needed dependencies. 从原始的ant分发中,首先运行“ant -f fetch.xml”(或类似的)来下载许多所需的依赖项。 Add these to your Eclipse project and see if it helps. 将这些添加到Eclipse项目中,看看它是否有帮助。

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). 我们已经从Ant为一个大型项目生成了Eclipse .classpath和.project文件,这些项目位于中心位置的jar(100+)(不包括src jar和javadoc)。 Similar to the build.xml linked from here with the obvious addition of the src and javadoc attributes. 类似于此处链接的build.xml,显然添加了src和javadoc属性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 您如何以编程方式从Eclipse构建路径中删除文件? - How do you programmatically remove a file from eclipse build path? 当构建文件位置更改时,如何在ANT中设置lib路径 - How to set lib path in ANT when the build file location changes Eclipse设置的Ant Java构建路径在编译时缺少库 - Ant Java Build Path set by Eclipse is Missing a Library at Compile Time 在ant构建脚本中,我可以引用其他构建文件中的路径吗? - In an ant build script, can I reference a path in a different build file? 如何在使用build.xml文件的Ant生成的jar文件中包含Eclipse项目的“Java Build Path”部分中引用的jar文件 - How to include the jars referenced in “Java Build Path” section of an Eclipse project in a jar file generated with Ant using a build.xml file 在ANT构建中设置类路径 - Setting up class path in ANT build 在Ant构建脚本中设置类路径 - Setting Class-Path in Ant build script 如何从在Eclipse中运行的ant文件中查找eclipse的路径? - How to find path of eclipse from within an ant file running in Eclipse? Eclipse Ant从1个项目构建Jar,然后移至另一个项目的构建路径 - Eclipse Ant build Jar from 1 project and move to build path of another project 如何配置Eclipse构建路径来开发Ant任务? 蚂蚁任务开发者有插件吗? - How to configure eclipse build path to develop an ant task ? Is there a plugin for ant tasks dev?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM