web-dev-qa-db-ja.com

JARおよびデバッグのためにリソースファイルを正しく参照する方法

MavenプロジェクトとJarファイルを使用するときにリソースを参照するという厄介な問題があります...

Eclipseのビルドパスの一部である専用フォルダー/ src/main/resourcesにすべてのリソースがあります。ファイルは次を使用して参照されます

getClass().getResource("/filename.txt")

これはEclipseでは正常に機能しますが、Jarファイルでは失敗します-リソースはjarのルートのすぐ下のフォルダーにあります...

JARとEclipseの両方でファイルを参照するための「ベストプラクティス」を知っている人はいますか?

編集: 問題は、リソースが実際には最上位のフォルダー「リソース」内のJARにあるのに、上記の方法ではファイルが見つからないことです...

41
Patrick

Mavenリソースフォルダーの内容がターゲット/クラスにコピーされ、そこから結果のJarファイルのルートにコピーされます。それが予想される動作です。

私が理解していないのは、あなたのシナリオの問題です。 getClass().getResource("/filename.txt")を介したリソースの参照は、クラスパス(またはその要素)が_target/classes_であるか、JARのルートであるかにかかわらず、クラスパスのルートで開始されます。表示される唯一のエラーは、間違ったClassLoaderを使用していることです。

リソースを使用するクラスがリソースと同じ成果物(JAR)にあることを確認し、ThatClass.class.getResource("/path/with/slash")またはThatClass.class.getClassLoader().getResource("path/without/slash")を実行します。

しかし、それとは別に:動作しない場合は、おそらくビルドプロセスのどこかで何か間違ったことをしている可能性があります。リソースがJARにあることを確認できますか?

18

同様の問題がありました。すべての組み合わせとデバッグを1日試した後、getClass()。getResourceAsStream( "resources/filename.txt")を試し、最終的に動作するようにしました。他に何も助けなかった。

18
andjelko

JARをパックすると、リソースファイルはファイルではなくストリームになります。そのため、getResourceは機能しません。

getResourceAsStreamを使用します。

「ファイル」コンテンツを取得するには、 https://commons.Apache.org/proper/commons-io/javadocs/api-release/org/Apache/commons/io/IOUtils.html を使用します。

static public String getFile(String fileName)
{
        //Get file from resources folder
        ClassLoader classLoader = (new A_CLASS()).getClass().getClassLoader();

        InputStream stream = classLoader.getResourceAsStream(fileName);

        try
        {
            if (stream == null)
            {
                throw new Exception("Cannot find file " + fileName);
            }

            return IOUtils.toString(stream);
        }
        catch (Exception e) {
            e.printStackTrace();

            System.exit(1);
        }

        return null;
}
17
Thomas Decaux