0

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() クラスへの呼び出し後、クラスがもう見つからない理由を知っている人はいますか? コンパイル タスクによって、システム クラスローダーが何らかの方法で変更されているように見えますか?

4

1 に答える 1

3

最近、JavaFileManager の再定義のカスタム実装で同様の問題に直面しました (とりわけ)。

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

なぜそのようにしたのかわかりませんが、あなたの場合のように、これはjdk6の下でうまくいきました。jdk7 の問題をこの関数に特定した理由の 1 つは、単体テスト (クラスローダーが 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 を見ると、一時ファイルマネージャーを提供することを期待していたことは明らかです (したがって、「可能」)「一般的な使用」のものではありません。

(いずれにせよ、この件に関する追加/ベストプラクティスの参考文献について知りたいです)

于 2013-02-19T15:38:18.050 に答える