Я беспокоюсь о ситуации, когда библиотеки Foo
и Bar
каждый раскрывает ресурс в пути к одному и тому же имени, скажем properties.txt
.Как избежать конфликтов ресурсов в библиотечных баночках?
Предполагая Maven созданы и jars
развернуты с Maven, если я это установить:
Library Foo:
$ cat Foo/src/main/resources/properties.txt
$ Foo
и библиотека Бар:
$ cat Bar/src/main/resources/properties.txt
$ Bar
И a App
, который зависит от них, pom
выглядит примерно так: в двух словах это просто говорит: «Создайте jar-with-dependencies и d epend на 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
-App
. Никаких предупреждений или ошибок при запуске, что неправильный файл, возможно, был выбран, на самом деле он потерпел неудачу молча.
Так что я хочу спросить правильную практику, чтобы избежать этого. Во-первых, что-то подобное должно терпеть неудачу громко, а не мягко. Во-вторых, единственным решением, которое я могу думать, является то, что все файлы ресурсов должны быть правильно упакованы, как и все остальное в Java-разработке, т. Е. Библиотека никогда не должна выставлять properties.txt
в «глобальное» пространство имен; он должен появиться в папке me/unroll/deptest/foo
, как и все остальное. Я скептически отношусь к тому, что я не видел примера Maven, который на самом деле это делает. Так что же лучше всего здесь?
* '/ src/test/resources'? – djechlin
@djechlin: спасибо! –
Итак, обратите внимание, что мой проект включает в себя пакет 'App', извлекающий ресурс в пакете' Bar'. Таким образом, на самом деле нужно было бы вызвать «App.class.getResourceAsStream» («/ me/unroll/bar/properties.txt») ', если namespaced этот путь, или' App.class.getClassLoader(). GetResourceAsStream ("me/unroll/bar /properties.txt ")'. Это правильная/хорошая практика? – djechlin