如何避免资源冲突的jar包?

问题描述 投票:5回答:2

我很担心,当库FooBar每个暴露在具有相同名称的类路径的资源的情况下,说properties.txt在这个例子。

假设一个Maven建立和jars部署使用Maven,如果我有这样的设置:

库富:

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

与图书馆吧:

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

而这取决于他们的App,其pom看起来是这样的 - 简而言之,这只是说:“建立一个罐子,有依赖性,并且依赖于FooBar

<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的例子,实际上做到这一点。那么,什么是最好的做法吗?

java maven packages dependency-management
2个回答
3
投票

您怎么用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()是默认的本地包装基础类。当然,当你要么FooBar的实例方法中,你简单地说getClass().getResourceAsStream("properties.txt")。此外,您还可以轻松地引用这两个文件,就像你引用类:

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

我很怀疑,因为我还没有看到任何Maven的例子,实际上做到这一点。

现实世界的例子:你有一个名为com.example.foo.FooTest Spring的集成测试。默认情况下,春季预计的背景文件驻留在:/src/test/resources/com/example/foo/FooTest-context.xml


1
投票

要使用Maven代码来做到这一点完成@托马斯的回答是:

<build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <targetPath>com/example/bar/</targetPath>
        </resource>
    </resources>
</build>
© www.soinside.com 2019 - 2024. All rights reserved.