2010-03-08 60 views
7

Có rất nhiều cuộc thảo luận về Ant và Eclipse, nhưng không có câu trả lời nào trước đó dường như giúp tôi.Làm cách nào để thiết lập đường dẫn xây dựng Eclipse và đường dẫn lớp từ tệp xây dựng Ant?

Đây là giao dịch: Tôi đang cố gắng xây dựng một chương trình Java biên dịch thành công với Ant từ dòng lệnh. (Để gây nhầm lẫn các vấn đề hơn nữa, chương trình tôi đang cố gắng biên dịch là bản thân Ant.)

Điều tôi thực sự muốn làm là đưa dự án này vào Eclipse và biên dịch nó trong Eclipse sao cho các ràng buộc kiểu và các ràng buộc biến (danh pháp từ Eclipse JDT) được giải quyết một cách chính xác. Tôi cần điều này vì tôi cần chạy một phân tích tĩnh trên mã được xây dựng trên đầu trang của JDT Eclipse. Cách thông thường tôi đưa một dự án Java vào Eclipse để Eclipse xây dựng nó và giải quyết tất cả các ràng buộc là chỉ cần nhập các thư mục nguồn vào một dự án Java, và sau đó yêu cầu nó sử dụng thư mục src/main/như một thư mục nguồn . "

Thật không may, làm điều đó với Ant làm cho việc xây dựng thất bại với nhiều lỗi biên dịch. Dường như với tôi rằng tệp xây dựng Ant đang thiết lập đường dẫn lớp và xây dựng đường dẫn chính xác (có thể bằng cách loại trừ các tệp nguồn nhất định) và Eclipse không có thông tin này.

Có cách nào để lấy đường dẫn lớp & thông tin đường dẫn xây dựng được nhúng trong tệp xây dựng Ant và đưa thông tin đó cho Eclipse để đưa vào tệp .project và .classpath của nó? Tôi đã thử, tạo một dự án mới từ một tệp xây dựng hiện có (một tùy chọn trong menu Tệp) nhưng điều này không giúp ích gì. Dự án vẫn có cùng lỗi biên dịch.

Cảm ơn, Nels

Trả lời

6

Tôi chưa bao giờ tìm thấy một cách thực sự trong sạch để làm điều đó, nhưng người ta "hackish" cách để làm điều đó là để thao tác sử dụng tập tin classpath nhật thực (điều này có chứa build path) .

Vì vậy, các classpath sẽ có nội dung trong nó như thế này:

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

Vì vậy, bạn có thể, ví dụ, hãy viết một số loại kịch bản hàng loạt, vv mà sẽ đọc phụ thuộc tập kiến ​​của bạn và đặt chúng vào tệp nhật thực .classpath (ở định dạng thích hợp, tất nhiên).

Nhưng cá nhân, tôi không bao giờ đánh lừa với những thứ như vậy. Những gì tôi làm chỉ là đặt tất cả các lọ nhu cầu dự án của tôi trong một thư mục, và sau đó trong tập tin kiến ​​của tôi, tôi có một con đường thiết lập như thế này:

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

test_reflib chỉ cần phải được xác định đến bất cứ nơi thư mục này là chứa tất cả các lọ.

Sau đó, ở phía nhật thực bạn chỉ có thể thực hiện "Thêm lọ" và điều hướng đến cùng một thư mục này và chỉ cần chọn tất cả các lọ. Thậm chí còn mát mẻ hơn là bất cứ khi nào bạn thả các lọ mới vào thư mục này, chỉ cần nhấp vào cấp độ gốc trong dự án eclipse và làm "Làm mới", sau đó chỉnh sửa đường dẫn xây dựng và nhấp vào thêm jar một lần nữa và nó sẽ chỉ hiển thị cho bạn các lọ mà bạn chưa thêm vào đường dẫn xây dựng (tức là lọ mới mà bạn vừa mới thả vào thư mục). Điều này rõ ràng là không hoạt động tốt nếu bạn đang chia sẻ các lọ ở một vị trí trung tâm, nhưng nó hoạt động khá tốt cho các dự án nhỏ hơn, nơi bạn có thể chỉ cần sao chép tất cả các lọ qua một thư mục tập trung cho dự án. Quay lại đầu trang

+0

Cảm ơn, điều này rất hữu ích. Tôi hy vọng một người nào đó đã phát triển loại kịch bản mà bạn mô tả. Đặc biệt, các tệp xây dựng này có nhiều điều kiện bao gồm và tôi muốn giải quyết chúng tự động. –

1

Từ bản phân phối kiến ​​thô, trước tiên hãy chạy "ant -f fetch.xml" (hoặc tương tự) để tải xuống rất nhiều phụ thuộc cần thiết. Thêm chúng vào dự án Eclipse của bạn và xem nó có giúp ích gì không.

+0

Đây không phải là câu trả lời chính xác mà tôi đang tìm kiếm, nhưng nó khá hữu ích, cảm ơn. –

1

Chúng tôi đã tạo tệp .classpath và .project Eclipse từ Ant cho một dự án lớn với các lọ nằm ở vị trí trung tâm (100+) (không tính src jars và javadocs). Tương tự như tệp build.xml được liên kết từ here với việc bổ sung rõ ràng các thuộc tính src và javadoc.

6

Tôi sử dụng ivy để quản lý đường dẫn ANT của mình, tôi đặc biệt khuyên bạn nên tìm hiểu cách hoạt động.

Có một eclipse plugin sẽ quản lý đường dẫn lớp nhật thực từ cùng một tệp ivy.xml mà ANT sử dụng để xác định phụ thuộc của nó.

2

Tôi đã viết một Tác vụ Ant tạo tệp Eclipse .userlibraries. Bạn có thể nhập tệp được tạo ra để tạo một thư viện người dùng trong Eclipse. Và sau đó sử dụng thư viện người dùng này như là một phần của đường dẫn xây dựng của bạn.

Để sử dụng nhiệm vụ thêm video này vào kiến ​​xây dựng tập tin của bạn:

<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. Nó yêu cầu ant.jar để chạy và biên dịch:

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); 
    } 
} 
Các vấn đề liên quan