CompilationTask.call()引入了ClassNotFoundException。在JDK6中工作,而不是在JDK7中工作

时间:2012-11-21 14:39:55

标签: java java-7 java-compiler-api

从JDK6迁移到JDK7后,下一个代码失败并出现 ClassNotFoundException

CompilationTask task = cSysCompiler.getTask(null, cFileManager, cDiagnosticCollector, null, null, cUnitsToCompile);
boolean mSuccess = task.call();
Analyzer mAnalyzer = new Analyzer(); // Throws ClassNotFoundException

解决方法:

ClassLoader mSystemClassLoader = ClassLoader.getSystemClassLoader();
mSystemClassLoader.loadClass("ft.jopc.com.JavaBytecodeObject");
mSystemClassLoader.loadClass("ft.jopc.com.analyzer.Analyzer");
mSystemClassLoader.loadClass("ft.jopc.opccl.ClassLoaderListener");
…
ompilationTask task = cSysCompiler.getTask(null, cFileManager, cDiagnosticCollector, null, null, cUnitsToCompile);
boolean mSuccess = task.call();
Analyzer mAnalyzer = new Analyzer(); // No ClassNotFoundException

有谁知道为什么在找不到对task.call()类的调用之后?看起来系统类加载器在某种程度上被编译任务改变了?

1 个答案:

答案 0 :(得分:3)

我们最近遇到了类似的问题,JavaFileManager的自定义实现重新定义(除其他外)

public ClassLoader getClassLoader(final Location location)
{
    return getClass().getClassLoader();
}

不确定为什么会这样做,但在你的情况下,这在jdk6下工作正常。我们将jdk7问题精确定位到这个函数部分是因为它在单元测试期间失败了(类加载器是Launcher $ AppClassLoader),但在“生产模式”(类由自定义类加载器加载)中工作正常。更改此函数以使用StandardFileManager版本,甚至只将其封装在空的URLClassloader中,例如

return new URLClassLoader(new URL[]{}, getClass().getClassLoader());

解决了这个问题。

显然它与介绍URLClassloader以及因此AppClassLoader在jdk7中为“可关闭”有关,如下所示:

Thread [main] (Suspended (breakpoint at line 282 in URLClassLoader))    
Launcher$AppClassLoader(URLClassLoader).close() line: 282 [local variables unavailable] 
JavacProcessingEnvironment.close() line: 1257   
JavaCompiler.initProcessAnnotations(Iterable<Processor>) line: 1004 
JavaCompiler.compile(List<JavaFileObject>, List<String>, Iterable<Processor>) line: 821 
Main.compile(String[], String[], Context, List<JavaFileObject>, Iterable<Processor>) line: 439  
JavacTaskImpl.call() line: 132  

然后,我必须承认我没有发现javadoc在这个主题上真的很清楚,但是看看jdk6 DefaultFileManager以及jdk7 BaseFileManager,似乎相当清楚,期望是提供一个临时文件管理器(因此需要关闭“如果可能”,而不是“通用”。

(我很乐意在任何情况下了解有关该主题的其他/最佳实践参考资料)