カスタム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