我担心库Foo
和Bar
每个库都在类路径上以相同名称公开资源的情况,例如properties.txt
在这个例子中。
假设一个 Maven 设置并jars
使用 Maven 部署,如果我有这个设置:
图书馆福:
$ cat Foo/src/main/resources/properties.txt
$ Foo
和图书馆酒吧:
$ cat Bar/src/main/resources/properties.txt
$ Bar
并且App
依赖于它们,它pom
看起来像这样 - 简而言之,这只是说“构建一个带有依赖关系的 jar,并依赖于Foo
and 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
。运行时没有警告或错误,可能选择了错误的文件,实际上它默默地失败了。
所以我想要求适当的练习来避免这种情况。一,这样的事情应该大声失败,而不是轻声细语。第二,我能想到的唯一解决方案是所有资源文件都应该像Java开发中的其他所有东西一样正确打包,即,一个库不应该暴露properties.txt
在“全局”命名空间中;它应该me/unroll/deptest/foo
像其他所有内容一样出现在一个文件夹中。我对此持怀疑态度,因为我还没有看到任何实际执行此操作的 Maven 示例。那么这里的最佳实践是什么?