は、開始点として使用してClass#getResourceAsStream()
いる場所を基準にしたパスをとることができます。Class
したがって、たとえば、クラスがcom.example
パッケージ内にあり、パスを要求するfoo/filename.properties
と、実際にファイルがロードされcom/example/foo/filename.properties
ます。ただし、を使用する/foo/filename.properties
と、実際にfoo/filename.properties
はクラスパスルートからロードされます。
だから、あなたのコード
java.util.Properties prop = new java.util.Properties();
String path = "localization/stat_codes.properties";
InputStream foo = prop.getClass().getResourceAsStream(path);
実際にファイルを探しjava/util/localization/stat_codes.properties
ます。
ただし、複雑な複数のクラスローダー階層を持つアプリケーションでは、一方のクラスローダーはもう一方のクラスローダーではありません。コアJavaクラスをロードしたクラスローダーは、必ずしもWebアプリケーションのにあるファイルに関する知識を持っているとは限りません/WEB-INF/classes
。したがって、パスの前にを付けることが/
必ずしも解決策になるとは限りませんが、それでも。を返しnull
ます。
現在のクラスがプロパティファイルと同じクラスローダーで表示されることを保証できる場合(たとえば、クラスパスの同じサブルートにあるため、/WEB-INF/classes
実際に使用する必要があります)
String path = "/localization/stat_codes.properties";
InputStream foo = this.getClass().getResourceAsStream(path);
ただし、ある時点で、実行時のメンテナンス/編集がより簡単になるためにプロパティファイルが外部化されるため、ファイルを編集するたびにWebアプリを再構築/再デプロイ/再起動する必要がない場合は、上記のコード行を参照してください。同様に失敗する可能性があります。外部化された場所には、別のクラスローダーからのみアクセスできます。正規の解決策は、代わりにスレッドのコンテキストクラスローダーを開始点として使用することです。これは、クラスパス内のすべてのリソースにアクセスできます。
String path = "localization/stat_codes.properties";
ClassLoader loader = Thread.currentThread().getContextClassLoader();
InputStream foo = loader.getResourceAsStream(path);
(これは、で始まるパスをとることができないことに注意してください。/
常に共通のルートを基準にしています)
参照: