java – 如何避免库jar中的资源冲突?

前端之家收集整理的这篇文章主要介绍了java – 如何避免库jar中的资源冲突?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

我很担心库Foo和Bar每个都在类路径上公开一个具有相同名称的资源,比如本例中的properties.txt.

假设一个Maven设置并且罐子与Maven一起部署,如果我有这个设置:

图书馆Foo:

$cat Foo/src/main/resources/properties.txt
$Foo

和图书馆酒吧:

$cat Bar/src/main/resources/properties.txt
$Bar

还有一个依赖于它们的应用程序,其pom看起来像这样 – 简而言之,这只是说“构建一个依赖于jar的jar,依赖于Foo和Bar:

问题是看起来像properties.txt文件被破坏了.让我们尝试一下罐子:

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

所以我在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打包应用程序时没有警告或错误.运行时可能没有选择错误文件时出现警告或错误,实际上它无声地失败.

所以我想要求正确的做法来避免这种情况.一,这样的事情应该大声失败,而不是轻声失败.第二,我能想到的唯一解决方案是所有资源文件都应该像Java开发中的其他所有资源一样正确打包,即库永远不会在“全局”命名空间中公开properties.txt;它应该出现在像me / unroll / deptest / foo这样的文件夹中,就像其他一切一样.我持怀疑态度,因为我没有看到任何实际上这样做的Maven示例.那么这里的最佳做法是什么?

最佳答案
你用Java做什么来避免库之间的冲突?套餐!这是已建立并且易于理解的方法.包也适用于资源:

com/example/foo/Foo.class
com/example/foo/properties.txt

和第二个图书馆:

com/example/bar/Bar.class
com/example/bar/properties.txt

请注意,properties.txt位于不同的包中,因此位于最终JAR中的目录中.实际上这种方法是首选,因为用于检索此类资源的API变得更容易:

App.class.getResourceAsStream("properties.txt"))

Bar.class.getResourceAsStream("properties.txt"))

它只是起作用,因为Class.getResourceAsStream()默认是本地的基础类包.当然,当你在Foo或Bar的实例方法中时,你只需要说getClass().getResourceAsStream(“properties.txt”).此外,您仍然可以轻松地引用这两个文件,就像您引用类一样:

getClass().getResourceAsStream("/com/example/foo/properties.txt");
getClass().getResourceAsStream("/com/example/bar/properties.txt");

I’m skeptical because I haven’t seen any Maven example that actually does this.

真实世界的例子:你有一个名为com.example.foo.FooTest的Spring集成测试.默认情况下,Spring期望上下文文件位于:/src/test/resources/com/example/foo/FooTest-context.xml下.

猜你在找的Java相关文章