2008-11-08 24 views
6

Trường hợp sử dụng của tôi là biên dịch các tệp nguồn được tạo từ một chương trình java bằng cách sử dụng các lớp ToolProvider và JavaCompiler được cung cấp trong JDK 6. Tệp nguồn chứa tham chiếu đến các lớp trong trình nạp lớp ngữ cảnh (nó chạy trong một thùng chứa J2EE), nhưng không có trong hệ thống bộ nạp lớp. Sự hiểu biết của tôi là theo mặc định ToolProvider sẽ tạo ra cá thể JavaCompiler với trình nạp lớp hệ thống.Làm cách nào để sử dụng JDK6 ToolProvider và JavaCompiler với trình nạp lớp ngữ cảnh?

Có cách nào để chỉ định trình nạp lớp cho JavaCompiler để sử dụng không?

tôi đã cố gắng tiếp cận này, biến đổi từ một cái gì đó trên IBM developerWorks:

FileManagerImpl fm = 
    new FileManagerImpl(compiler.getStandardFileManager(null, null, null);); 

với FileManagerImpl định nghĩa là:

static final class FileManagerImpl 
    extends ForwardingJavaFileManager<JavaFileManager> { 

    public FileManagerImpl(JavaFileManager fileManager) { 
     super(fileManager); 
    } 

    @Override 
    public ClassLoader getClassLoader(JavaFileManager.Location location) { 
     new Exception().printStackTrace(); 
     return Thread.currentThread().getContextClassLoader(); 
    } 

} 

Các stacktrace chỉ ra nó chỉ được gọi là một lần trong quá trình chú thích. Tôi đã xác minh lớp được tham chiếu trong tệp nguồn được biên dịch không nằm trên đường dẫn lớp hệ thống nhưng có sẵn từ trình nạp lớp ngữ cảnh.

Trả lời

1

Một tùy chọn khác là sử dụng Commons JCI.

+0

Dường như JCI không cho phép bạn chuyển bộ nạp lớp vào, chỉ đường dẫn, giống như hỗ trợ JDK6 cho phép. – Phil

+0

Bạn đang tìm kiếm ở đâu? Chắc chắn rồi. – tcurdt

8

Nếu bạn biết classpath để các tập tin mà được biết đến contextclassloader bạn có thể vượt qua chúng để trình biên dịch:

StandardJavaFileManager fileManager = compiler.getStandardFileManager(this /* diagnosticlistener */, null, null); 
// get compilationunits from somewhere, for instance via fileManager.getJavaFileObjectsFromFiles(List<file> files) 
List<String> options = new ArrayList<String>(); 
options.add("-classpath"); 
StringBuilder sb = new StringBuilder(); 
URLClassLoader urlClassLoader = (URLClassLoader) Thread.currentThread().getContextClassLoader(); 
for (URL url : urlClassLoader.getURLs()) 
    sb.append(url.getFile()).append(File.pathSeparator); 
options.add(sb.toString()); 
CompilationTask task = compiler.getTask(null, fileManager, this /* diagnosticlistener */, options, null, compilationUnits); 
task.call(); 

Ví dụ này giả sử bạn đang sử dụng một URLClassLoader (cho phép bạn để lấy classpath) nhưng bạn có thể chèn classpath của riêng bạn nếu bạn muốn.

0

Bạn đang đặt hai câu hỏi riêng tại đây.

Một là cách biên dịch các lớp không tìm thấy trong đường dẫn lớp hệ thống. Điều này có thể dễ dàng được giải quyết bằng cách chuyển đối số dòng lệnh "-classpath" tới trình biên dịch (như được đề cập lần đầu bởi Leihca).

Cách thứ hai là cách khởi tạo ToolProvider và JavaCompiler trên trình nạp lớp ngữ cảnh của luồng. Tại thời điểm viết bài này, đây là câu hỏi chưa được giải quyết: Using javax.tools.ToolProvider from a custom classloader?

Các vấn đề liên quan