2010-03-08 184 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); 
    } 
}