web-dev-qa-db-ja.com

実行可能jar内のClass.getResource()およびClassLoader.getResource()の奇妙な動作

Class.getResource()とClassLoader.getResource()の違いは何ですか? および独自のコードから、

_getClass().getResource("/path/image.png")
_

と同じです

_getClass().getClassLoader().getResource("path/image.png")
_

投稿 jarファイルの画像を読み取れません は、

_getClass().getClassLoader().getResource("path/image.png")
_

実行可能jarファイルではnullを返しますが、

_getClass().getResource("/path/image.png")
_

正しいURLを返します。

Since Class.getResource()は、先頭のスラッシュを削除した後、ClassLoader.getResource()に委任します。これらの呼び出しは同一であると予想しますが、明らかにこの場合はそうではありません。特別なクラスローダーが特定のクラスにアタッチされている場合でも、呼び出しごとに同じものである必要があり、同じ動作になります。

だから、質問は次のとおりです:次のコードが最初の呼び出しではnullを返し、2番目の呼び出しでは適切なURLを返す明らかな状況はありますか?

_package com.example;

import Java.net.URL;

public class ResourceTest {

   public void run() {
      URL iconUrl1 = getClass().getClassLoader().getResource("path/image.png");
      System.out.println("ClassLoader.getResource(\"path/image.png\"): " + iconUrl1);

      URL iconUrl2 = getClass().getResource("/path/image.png");
      System.out.println("Class.getResource(\"/path/image.png\"): " + iconUrl2);
   }

   public static void main(String[] args) {
      ResourceTest app = new ResourceTest();
      app.run();
   }
}
_
34
Andreas Fester

この質問はすでに質問され、答えられていると思いました!

getClass().getResource()は.classファイルに関連して検索し、getClass().getClassLoader().getResource()はクラスパスルートに関連して検索します。

ここにSSCCEがある場合、なぜそうならないのかわかりません

1).jarのディレクトリ構成を表示し、...

2)パッケージを考慮に入れる

Q:まだ回答されていない(もしあれば) Class.getResource()とClassLoader.getResource()の違いは何ですか? (およびそれが引用するリンク)?

================================================== =======================

何が明確でないのかはまだわかりませんが、この例は役に立つかもしれません:

_/*
  SAMPLE OUTPUT:
  ClassLoader.getResource(/subdir/readme.txt): NULL
  Class.getResource(/subdir/readme.txt): SUCCESS

  ClassLoader.getResource(subdir/readme.txt): SUCCESS
  Class.getResource(subdir/readme.txt): NULL
 */
package com.so.resourcetest;

import Java.net.URL;

public class ResourceTest {

    public static void main(String[] args) {
        ResourceTest app = new ResourceTest ();
    }

    public ResourceTest () {
        doClassLoaderGetResource ("/subdir/readme.txt");
        doClassGetResource ("/subdir/readme.txt");
        doClassLoaderGetResource ("subdir/readme.txt");
        doClassGetResource ("subdir/readme.txt");
    }

    private void doClassLoaderGetResource (String sPath) {
        URL url  = getClass().getClassLoader().getResource(sPath);
        if (url == null)
            System.out.println("ClassLoader.getResource(" + sPath + "): NULL");
        else
            System.out.println("ClassLoader.getResource(" + sPath + "): SUCCESS");
    }

    private void doClassGetResource (String sPath) {
        URL url  = getClass().getResource(sPath);
        if (url == null)
            System.out.println("Class.getResource(" + sPath + "): NULL");
        else
            System.out.println("Class.getResource(" + sPath + "): SUCCESS");
    }
}
_

対応するディレクトリツリーを次に示します。たまたまEclipseプロジェクトですが、ディレクトリはEclipse、Netbeans ...または.jarファイルに関係なく同じです:

_C:.
├───.settings
├───bin
│   ├───com
│   │   └───so
│   │       └───resourcetest
│   └───subdir
└───src
    ├───com
    │   └───so
    │       └───resourcetest
    └───subdir
_

開かれているファイルは「subdir/readme.txt」です


付録11/12/9:

こんにちは -

あなたのコードをgithubから逐語的にコピーし、再コンパイルして再実行しました:

_ClassLoader.getResource(/subdir/readme.txt): NULL
Class.getResource(/subdir/readme.txt): SUCCESS
ClassLoader.getResource(subdir/readme.txt): SUCCESS
Class.getResource(subdir/readme.txt): NULL
_

それがnotの場合、あなたが得ている出力は...私は困惑しています。

それが価値があるものは何でも、私は実行しています:

  • Eclipse Indigo(問題ではない)

  • IDEの内部で実行します(IDEの内部または外部で、ファイルシステムまたは.jarのどちらでもかまいません)

  • 私のJREは1.6です(もしあれば、これはおそらく大物です)

申し訳ありませんが、私の考えが簡単な問題であったことを解決できませんでした:(


付録11/12/21(アンドレアス):

この質問に関する最近の活動はなかったので、発見したことを要約したいと思います。

  • 一般的な理解から、上記の質問に対する答えは次のとおりです。 "いいえ、Class.getResource("/path/image.png")が有効なURLを返すことはできませんが、ClassLoader.getResource("path/image.png") nullを返します "
    • ClassLoader.getResource()とClass.getResource()の違いは完全に明確です。
    • サンプル出力は、「成功」と「ヌル」の両方で一致します
    • サンプル出力は、予想と一致します
    • 結論:何かを監督したか、別の何かがリンクされた質問で説明されている「解決策」を機能させました。現在、どちらかを証明することはできないと思います。
39
paulsm4