Как установить путь сборки Eclipse и путь к классу из файла сборки Ant?

Существует много дискуссий о Ant и Eclipse, но, похоже, ни один из предыдущих ответов мне не помог.

Вот в чем дело: я пытаюсь создать программу на Java, которая успешно компилируется с помощью Ant из командной строки. (Чтобы еще больше запутать ситуацию, программа, которую я пытаюсь скомпилировать, — это сам Ant.)

Что я действительно хочу сделать, так это перенести этот проект в Eclipse и скомпилировать его в Eclipse, чтобы привязки типов и привязки переменных (номенклатура из Eclipse JDT) были правильно разрешены. Мне это нужно, потому что мне нужно запустить статический анализ кода, созданного поверх Eclipse JDT. Обычный способ, которым я добавляю проект Java в Eclipse, чтобы Eclipse построил его и разрешил все привязки, — это просто импортировать исходные каталоги в проект Java, а затем указать ему использовать каталог src/main/ в качестве «исходного каталога». ."

К сожалению, выполнение этого с помощью Ant приводит к сбою сборки с многочисленными ошибками компиляции. Мне кажется, что файл сборки Ant правильно настраивает путь к классу и путь сборки (возможно, путем исключения определенных исходных файлов), а Eclipse не имеет этой информации.

Есть ли способ получить информацию о пути к классу и пути сборки, встроенную в файл сборки Ant, и предоставить эту информацию Eclipse для помещения в свои файлы .project и .classpath? Я пытался создать новый проект из существующего файла сборки (параметр в меню «Файл»), но это не помогает. В проекте все те же ошибки компиляции.

Спасибо, Нельс


person Nels Beckman    schedule 08.03.2010    source источник


Ответы (5)


Я никогда не находил действительно чистый способ сделать это, но один «хакерский» способ сделать это - манипулировать файлом .classpath, который использует eclipse (это содержит путь сборки).

Таким образом, в .classpath будут такие вещи:

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

Таким образом, вы можете, например, написать какой-то пакетный скрипт и т. д., Который будет читать ваши зависимости файла ant и помещать их в файл eclipse .classpath (конечно, в правильном формате).

Но лично я никогда не морочусь с такими вещами. Что я делаю, так это просто помещаю все jar-файлы, которые нужны моему проекту, в одну папку, а затем в моем файле ant у меня есть путь, настроенный следующим образом:

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

test_reflib просто нужно определить, где находится эта папка, содержащая все банки.

Затем на стороне затмения вы можете просто сделать «Добавить банки», перейти к этой же папке и просто выбрать все банки. Что еще круче, так это то, что каждый раз, когда вы добавляете новые банки в эту папку, просто щелкните корневой уровень в проекте eclipse и выполните «Обновить», а затем отредактируйте путь сборки и снова нажмите «Добавить банку», и он покажет вам только банки который вы еще не добавили в путь сборки (т. е. новый jar-файл, который вы только что поместили в папку).

Это, очевидно, не работает слишком хорошо, если вы делитесь jar-файлами в центральном месте, но это работает очень хорошо для небольших проектов, где вы можете просто скопировать все jar-файлы в централизованную папку для проекта.

person dcp    schedule 08.03.2010
comment
Спасибо, это полезно. Я надеюсь, что кто-то уже разработал сценарий, который вы описываете. В частности, эти файлы сборки имеют множество условных включений, и я хотел бы разрешить их автоматически. - person Nels Beckman; 16.03.2010

Я использую ivy для управления путями к классам ANT, я настоятельно рекомендую изучить, как это работает.

Существует плагин eclipse, который будет управлять путем к классам eclipse. из того же файла ivy.xml, который ANT использует для определения своих зависимостей.

person Mark O'Connor    schedule 16.03.2010

Я написал задачу 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.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);
    }
}
person Javier S López    schedule 30.03.2014

Из необработанного дистрибутива ant сначала запустите «ant -f fetch.xml» (или аналогичный), чтобы загрузить множество необходимых зависимостей. Добавьте их в свой проект Eclipse и посмотрите, поможет ли это.

person Thorbjørn Ravn Andersen    schedule 08.03.2010
comment
Это был не совсем тот ответ, который я искал, но он был весьма полезен, спасибо. - person Nels Beckman; 16.03.2010

Мы создали файлы Eclipse .classpath и .project из Ant для большого проекта с централизованно расположенными jar-файлами (более 100) (не считая jar-файлов src и javadocs). Аналогичен файлу build.xml, ссылка на который приведена здесь с очевидным добавлением src и атрибуты javadoc.

person EGHM    schedule 16.03.2010