カスタムClassLoader、jarパッケージがjarパッケージプロファイルをロードできない問題
2598 ワード
カスタムClassLoaderさんを書くことができて、あなたもClassLoaderに対して一定の認識があると信じています.あるいはあなたも私を困惑させることができます.....
URLClassLoaderは主に外部jarパッケージのロードに適用され、通常、URLClassLoaderによって追加のjarパッケージをロードして依存競合の問題を解決します.
しかし、テスト中に異常が報告されました.
Illegal Hadoop Version: Unknown (expected A.B.* format)
Jar内ではhadoopコンポーネントが使用するが、hadoopはclasspathの下のcommon-version-infoを読み取ることができない.propertiesプロファイル.
hadoopのここのソースコードを大体読みました.
protected VersionInfo(String component) {
info = new Properties();
String versionInfoFile = component + "-version-info.properties";
InputStream is = null;
try {
is = Thread.currentThread().getContextClassLoader()
.getResourceAsStream(versionInfoFile);
if (is == null) {
throw new IOException("Resource not found");
}
info.load(is);
} catch (IOException ex) {
LogFactory.getLog(getClass()).warn("Could not read '" +
versionInfoFile + "', " + ex.toString(), ex);
} finally {
IOUtils.closeStream(is);
}
}
ソースコードの検出:
Thread.currentThread().getContextClassLoader() .getResourceAsStream(versionInfoFile);
読み取りの構成.
そこで私はカスタムClassLoaderで、現在のClassLoaderをスレッドのClassLoaderに入れました.コードは以下の通りです.
ClassLoader classLoader = new URLClassLoader(new URL[]{new URL(url)}, Thread.currentThread().getContextClassLoader());
Thread.currentThread().setContextClassLoader(classLoader);
再テスト、テストに合格~
===========================================================================
いくつか質問があります.
1.Thread.currentThread().getContextClassLoader() .getResourceAsStream方式はjarパッケージ内の構成をロードできないのはなぜですか?呼び出し元のスレッドにClassLoaderを追加した後、この方式はロードできますか?
正直に言うと、私が考えているのはよくわかりませんが、両親が委任したURLClassLoader Aをカスタマイズしてjarパッケージをロードすると、jarパッケージ内のclassの親クラスローダはAであるべきですが、Aを現在のスレッドのクラスローダに入れないとテストしたら、jarパッケージ内のクラスローダはAppClassLoaderで構成がロードされず、Aを現在のスレッドのクラスローダに入れると、JArパッケージ内のクラスローダはURLClassLoaderで構成にロードできる~~
もう一度テストしました.currentThread().getContextClassLoader() .getResourceAsStream方式で構成をロードし、Classxxを使用する.class.getClassLoader().getResourceAsStreamは構成をロードし、カスタムURLClassLoader Aを現在のスレッドのクラスローダに入れない.jarパッケージ内のクラスローダはAppClassLoaderで構成をロードできる!!Aを現在のスレッドのクラスローダに入れ、jarパッケージ内のクラスローダはURLClassLoaderで構成にもロードできます!!!
あるスレッドはカスタムURLClassLoaderでjarパッケージのクラスをロードします.jarパッケージのクラスがロードした親はいったいカスタムURLClassLoaderではありませんか.上記のテストでスレッド内で使用する場合はThread.currentThread().setContextClassLoader(classLoader);ではjarパッケージ内用のClassLoaderは必ずURLClassLoaderです.そうでない場合はAppClassLoaderを使用します.
どの兄が私の疑問を解決できるのかTT