我想用Java編譯器API來編譯一些java類。該類從jar文件中導入一些可以通過上下文ClassLoader加載的包,我們稱之爲X,它不是系統類加載器。當我運行編譯時,編譯器抱怨沒有識別導入。我試圖指定fileManager來傳遞類加載器,但它沒有幫助。Java編譯器API類加載器
當編譯方法被調用時,它首先打印「CLASS LOADED」,所以上下文ClassLoader可以找到依賴類。然而,編譯本身失敗(我收到「編譯失敗」消息),並在編譯期間,我得到這樣的錯誤:
/path/to/my/Source.java:3:包my.dependency不存在 導入my.dependency.MyClass; ^
我在做什麼錯?將自定義類加載器傳遞給compilationTask的正確方法是什麼?我不能從ClassLoader中提取URL,因爲它不是URLClassLoader。
我的方法在這裏:
public void compile(List<File> filesToCompile) {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager stdFileManager =
compiler.getStandardFileManager(null, null, null);
Iterable<? extends JavaFileObject> fileObjects = stdFileManager
.getJavaFileObjectsFromFiles(filesToCompile);
FileManagerImpl fileManager = new FileManagerImpl(stdFileManager);
CompilationTask task = compiler.getTask(null, fileManager, null, null, null, fileObjects);
Boolean result = task.call();
if (result == true) {
System.out.println("Compilation has succeeded");
} else {
System.out.println("Compilation FAILED");
}
}
private final class FileManagerImpl extends ForwardingJavaFileManager<JavaFileManager> {
public FileManagerImpl(JavaFileManager fileManager) {
super(fileManager);
}
@Override
public ClassLoader getClassLoader(JavaFileManager.Location location) {
ClassLoader def = getContextClassLoader();
try {
def.loadClass("my.dependency.MyClass");
System.out.println("CLASS LOADED");
} catch (ClassNotFoundException ex) {
System.out.println("NOT LOADED");
}
return def;
}
}
非常感謝,我會檢查出來。但是,沒有辦法設置現有的classLoader嗎? – 2011-04-28 13:47:57
@Pavel S. - 我懷疑它是否合理,爲編譯器工具提供一個與實際應用程序類路徑分開的類路徑。想象一下,你已經加載了一個類的一個版本,但想用另一個版本來編譯這些類。這*需要*類分離。 – 2011-04-28 13:51:38