Foo
この例のように、ライブラリとBar
それぞれが同じ名前のクラスパス上のリソースを公開する状況が心配ですproperties.txt
。
Mavenがセットアップされ、Mavenjars
とともにデプロイされていると仮定すると、これをセットアップしている場合は次のようになります。
Library Foo:
$ cat Foo/src/main/resources/properties.txt
$ Foo
およびライブラリバー:
$ cat Bar/src/main/resources/properties.txt
$ Bar
そして、App
それは彼らに依存し、そのpom
ように見えます-一言で言えば、これは単に「依存関係のある瓶を構築し、依存し、Foo
そしてBar
:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>bundle-project-sources</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<archive>
<manifest>
<mainClass>me.unroll.deptest.App</mainClass>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
</manifest>
<manifestEntries>
<Implementation-Build>${buildNumber}</Implementation-Build>
</manifestEntries>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</execution>
</executions>
</plugin>
properties.txt
問題は、ファイルが破壊されたように見えることです。試してみましょうjar tf
:
unrollme-dev-dan:target Dan$ jar tf App-1.0-SNAPSHOT-jar-with-dependencies.jar
META-INF/
META-INF/MANIFEST.MF
properties.txt
META-INF/maven/
META-INF/maven/me.unroll.deptest/
META-INF/maven/me.unroll.deptest/Bar/
META-INF/maven/me.unroll.deptest/Bar/pom.xml
META-INF/maven/me.unroll.deptest/Bar/pom.properties
META-INF/maven/me.unroll.deptest/Foo/
META-INF/maven/me.unroll.deptest/Foo/pom.xml
META-INF/maven/me.unroll.deptest/Foo/pom.properties
me/
me/unroll/
me/unroll/deptest/
me/unroll/deptest/App.class
だから私はその中でmain
クラスを実行しましたApp
:
try (InputStream is = App.class.getClassLoader().getResourceAsStream("properties.txt")) {
java.util.Scanner s = new java.util.Scanner(is);
System.out.println("Scanner: " + s.next());
}
そして、出力は次のとおりです。
unrollme-dev-dan:target Dan$ java -jar App-1.0-SNAPSHOT-jar-with-dependencies.jar
Scanner: Bar
おっと、バーが勝った。mvn package
-ing時に警告やエラーは発生しませんApp
。実行時に間違ったファイルが選択された可能性があるという警告やエラーはありません。実際、サイレントに失敗しました。
ですから、これを避けるために適切な練習をお願いしたいと思います。1つは、このようなものは、静かにではなく、大声で失敗するはずです。2つ目は、私が考えることができる唯一の解決策は、すべてのリソースファイルをJava開発の他のすべてと同じように適切にパッケージ化する必要があることです。つまり、ライブラリはproperties.txt
「グローバル」名前空間で公開しないでください。me/unroll/deptest/foo
他のすべてと同じようにフォルダに表示されるはずです。実際にこれを行うMavenの例を見たことがないので、私は懐疑的です。では、ここでのベストプラクティスは何ですか?