web-dev-qa-db-ja.com

jarに含まれるリソースをロードする

私のアプリケーションでは、次の方法でリソースをロードします。

WinProcessor.class.getResource("repository").toString();

そしてこれは私に与えます:

file:/root/app/repository   (and I replace "file:" with empty string)

IDEからアプリケーションを実行すると問題なく動作しますが、アプリケーションのjarを実行すると次のようになります。

Java -jar app.jar

パスは次のようになります。

jar:/root/app.jar!/repository

この問題を解決する方法はありますか?

これを作成するために、「リポジトリ」ディレクトリ名を使用します。

ConfigurationContext ctx = (ConfigurationContext) ConfigurationContextFactory.createConfigurationContextFromFileSystem(repositoryString, null);

同じ方法で、(dirではなく)1つのファイル名を取得し、次のように使用します。

System.setProperty("javax.net.ssl.trustStore", fileNameString)
21
Giancarlo

FileInputStreamなどを使用してリソースをロードしようとしているようです。しないでください:getResourceを呼び出す代わりに、 getResourceAsStream を呼び出して、そこからデータを読み取ります。

(代わりにURLからリソースをロードすることもできますが、getResourceAsStreamを呼び出す方が少し便利です。)

編集:あなたの更新された答えを見て、コードの他のビットはファイルシステムの物理的な単一ファイルにあるデータに依存しているようです。したがって、答えはそもそもそれをjarファイルにバンドルしないことです。あなたはできましたそれが別のファイルにあるかどうかを確認し、それが一時ファイルに抽出されていない場合は、それはかなりハックなIMOです。

35
Jon Skeet

_Java -jar app.jar_を使用してコードを実行する場合、Javaは、JARファイルのマニフェストで定義されたクラスパスのみを使用します(つまり、_Class-Path_属性)。クラスが_app.jar_、またはクラスがJARのマニフェストの_Class-Path_属性で設定されたクラスパスにある場合、次のコードスニペットを使用してそのクラスをロードできます。ここで、classNameは完全修飾ですクラス名。

_final String classAsPath = className.replace('.', '/') + ".class";
final InputStream input = ClassLoader.getSystemResourceAsStream( path/to/class );
_

クラスがJARの一部ではなく、マニフェストの_Class-Path_にない場合、クラスローダーはそれを見つけません。代わりに、URLClassLoaderを使用できます。ただし、ウィンドウとUnix/Linux/MacOSXの違いに注意して対処してください。

_// the class to load
final String classAsPath = className.replace('.', '/') + ".class";

// the URL to the `app.jar` file (Windows and Unix/Linux/MacOSX below)
final URL url = new URL( "file", null, "///C:/Users/diffusive/app.jar" );
//final URL url = new URL( "file", null, "/Users/diffusive/app.jar" );

// create the class loader with the JAR file
final URLClassLoader urlClassLoader = new URLClassLoader( new URL[] { url } );

// grab the resource, through, this time from the `URLClassLoader` object
// rather than from the `ClassLoader` class
final InputStream input = urlClassLoader.getResourceAsStream( classAsPath );
_

どちらの例でも、例外と、リソースが見つからない場合の入力ストリームがnullであるという事実に対処する必要があります。また、InputStreamを_byte[]_に入れる必要がある場合は、ApacheのコモンズIOUtils.toByteArray(...)を使用できます。また、Classが必要な場合は、クラスローダーのdefineClass(...)メソッドを使用できます。このメソッドは、_byte[]_を受け入れます。

このコードは、Diffusiveソースコードの ClassLoaderUtils クラスにあります。SourceForgeのgithub.com/robphilipp/diffusiveにあります。

RestfulDiffuserManagerResource.createJarClassPath(...) の相対パスと絶対パスからWindowsおよびUnix/Linux/MacOSXのURLを作成する方法

8
Rob Philipp

URLを作成すると、 openStream メソッドを使用して、リソースを(jarファイルでも)ロードできます。

5
Konrad Rudolph