Webアプリが依存するjarファイルの1つが、jarファイル内からプロパティファイルを読み込もうとすると、問題が発生します。 jarのコードは次のとおりです。
static
{
Properties props = new Properties();
try
{
props.load(ClassLoader.getSystemResourceAsStream("someProps.properties"));
} catch (IOException e)
{
e.printStackTrace();
}
someProperty = props.getProperty("someKey");
}
プロパティファイルは、Mavenプロジェクトの「src/main/resources」ディレクトリにあります。 Eclipseのjunitテストからこのコードを実行すると、問題なく実行されます。 Mavenを使用してプロジェクトをjarにビルドし、Webアプリに依存関係として含めると、プロパティファイルが見つかりません。プロパティファイルが依存するjarのベースディレクトリにあることは知っていますが、これを修正する方法はわかりません。
問題は、getSystemResourceAsStream
を使用していることです。単にgetResourceAsStream
を使用します。システムリソースは、システムクラスローダーからロードします。これは、ほぼ確実に、webappとして実行するときにjarがロードされるクラスローダーではありません。
Eclipseで動作します。これは、アプリケーションを起動すると、クラスパスの一部としてjarでシステムクラスローダーが設定されるためです。 (たとえばJava -jar my.jarはシステムクラスローダーでmy.jarをロードします。)これはWebアプリケーションには当てはまりません。アプリケーションサーバーは複雑なクラスロードを使用してWebアプリケーションを相互に分離します。アプリケーションサーバーの内部から、たとえば、 Tomcat classloader how-to 、および使用されるクラスローダー階層の図を参照してください。
編集:通常、getClass().getResourceAsStream()
を呼び出してクラスパス内のリソースを取得しますが、静的イニシャライザーでリソースをフェッチしているため、目的のクラスローダーにあるクラスに明示的に名前を付ける必要がありますからロードします。最も簡単なアプローチは、静的初期化子を含むクラスを使用することです。
[public] class MyClass {
static
{
...
props.load(MyClass.class.getResourceAsStream("/someProps.properties"));
}
}
レコードについては、これは JARにリソースを追加するにはどうすればよいですか? (単体テストに示されていますが、「通常の」リソースにも同じことが言えます)に記載されています。
ユニットテストのクラスパスにリソースを追加するには、リソースをJARに追加する場合と同じパターンに従いますが、リソースを配置するディレクトリは
${basedir}/src/test/resources
。この時点で、プロジェクトディレクトリ構造は次のようになります。my-app |-- pom.xml `-- src |-- main | |-- Java | | `-- com | | `-- mycompany | | `-- app | | `-- App.Java | `-- resources | `-- META-INF | |-- application.properties `-- test |-- Java | `-- com | `-- mycompany | `-- app | `-- AppTest.Java `-- resources `-- test.properties
単体テストでは、次のような簡単なコードスニペットを使用して、テストに必要なリソースにアクセスできます。
... // Retrieve resource InputStream is = getClass().getResourceAsStream("/test.properties" ); // Do something with the resource ...