Использовать ресурсы зависимостей?
В моем проекте Maven есть один модуль (ядро), который имеет несколько ресурсов для своих классов. При запуске классов внутри модуля он может получить свои собственные ресурсы. Все работает нормально.
В тех случаях, когда разрывы вещей - это когда другой модуль, который зависит от ядра, пытается запустить этот класс. Папка, в которой Java ищет ресурсы, - это этот модуль, а не основной модуль. Таким образом, класс терпит неудачу.
Вкратце: как я могу получить доступ к ресурсам зависимости?
Я экспериментировал с попыткой сделать это, объявив в Core JAR Manifest Class-Path: .
. Однако при перечислении ресурсов, доступных с помощью JSHookLoader.class.getClassLoader().getResources("");
(JSHookLoader находится в Core, если это что-то означает), я получаю:
Resource: W:\programming\quackbot-hg\impl\target\classes
File rebel.xml
Resource: W:\programming\maven-repo\org\quackbot\core\3.5-SNAPSHOT
File core-3.5-SNAPSHOT.jar
File core-3.5-SNAPSHOT.pom
File maven-metadata-local.xml
File _maven.repositories
Это, конечно, усложняет ситуацию, поскольку я ожидал, что JAR сам будет в Classpath, а не в каталоге JAR в
Любые предложения?
Возвращаясь к этому проекту, у меня все еще есть эта проблема. Другие руководства говорили о том, как использовать плагин maven-assembly-plug-in и плагин удаленных ресурсов, но это очень больно, поскольку все модули должны включать XML файл монстра.
Почему бы мне не упростить вопрос: как я могу добавить JAR зависимостей в список ресурсов?
- В core.jar есть несколько ресурсов в папке/ресурсах. Запуск core.jar Я могу увидеть/ресурсы в списке ресурсов.
- impl.jar зависит от core.jar. После запуска, хотя /resources не входит в список ресурсов и, следовательно, вызывает хаос.
Это должно быть достаточно простым, но как я могу это сделать? Я трачу часы, пытаясь понять простой способ сделать это, но безрезультатно.
Ответы
Ответ 1
После многих поисков я наконец наткнулся на решение.
Мое решение принимает основной модуль и распаковывает его с помощью Maven Dependency Plugin, поэтому исключает папку META-INF и папку org, в которой находятся скомпилированные классы. Причина, по которой я исключаю то, чего я не хочу, вместо того, чтобы явно заявлять, что хочу, - это то, что новые ресурсы могут быть легко добавлены без необходимости постоянно обновлять POM.
Причина, по которой я не использую плагин сборки или плагин удаленных ресурсов, заключается в том, что они используют выделенные ресурсы. Я не думаю, что мне нужно будет создать основной модуль и модуль основных ресурсов, причем модуль основных ресурсов содержит только файлы конфигурации резервного копирования и спящего режима + некоторые другие вещи.
Вот копия того, что я использую для этого
<build>
<plugins>
<!--Extract core resources-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.2</version>
<executions>
<execution>
<id>unpack</id>
<phase>generate-resources</phase>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<configuration>
<includeGroupIds>${project.groupId}</includeGroupIds>
<includeArtifactIds>core</includeArtifactIds>
<excludeTransitive>true</excludeTransitive>
<overWrite>true</overWrite>
<outputDirectory>${project.build.directory}/core-resources</outputDirectory>
<excludes>org/**,META-INF/**,rebel.xml</excludes>
<overWriteReleases>true</overWriteReleases>
<overWriteSnapshots>true</overWriteSnapshots>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
<!--New resource locations-->
<resources>
<resource>
<filtering>false</filtering>
<directory>${project.build.directory}/core-resources</directory>
</resource>
<resource>
<filtering>false</filtering>
<directory>${basedir}/src/main/resources</directory>
</resource>
</resources>
</build>
Ответ 2
Если ресурсы находятся в классах /src/main/resources
и в JAR, они обращаются к ним с помощью getResourceAsStream()
, вы также сможете получить доступ к этим файлам из классов в других JAR (также используя getResourceAsStream()
). Это связано с тем, что все файлы, расположенные в /src/main/resources
, в конечном итоге попадают в один и тот же логический каталог (CLASSPATH
). Другими словами: все файлы, расположенные в /src/main/resources
, и все классы, скомпилированные из /src/main/java
, являются, так сказать, объединенными в одно пространство имен.
Если вы все еще не можете получить доступ к файлам, хотя все классы используют унифицированный API getResourceAsStream()
, у вас могут быть проблемы с видимостью класса.
Ответ 3
Если ваш зависимый JAR имеет класс с именем OneDependent, то это должно работать:
OneDependent.class.getResourceAsStream(resourcePath)
Ответ 4
Я не думаю, что это хорошая идея. Предположим, у вас есть модуль A
. Это зависит от "B". 'B' зависит от C
. В принципе, вы должны заботиться о A
только о интерфейсе модуля B
. Возможно, завтра
он меняет зависимость от C
до D
. Если это произойдет, вам понадобится изменить A
. Это не хорошая ситуация, не так ли? Поэтому объявляйте зависимость A
от C
неявным способом.
Вкратце: как я могу получить доступ к ресурсам зависимости?
Короче: объявите эту зависимость напрямую.
Ответ 5
У меня была похожая ситуация только сейчас. У меня есть "создатель тестового кода", который берет данные из каталога src/test/resources и передает данные в базу данных H2. Прекрасно работает с модулем A, но при вызове из модуля B этого не произошло. Он создает путь с несколькими полуколонами (из-за ресурсов, находящихся в файле jar); moduleA затем не находит файлы "локальные для себя".
В конце я добавил
<testResources>
<testResource>
<directory>src/test/resources</directory>
</testResource>
<testResource>
<directory>../moduleA/src/test/resources</directory>
</testResource>
</testResources>
в модуль сборки модуля, и теперь сборка проходит через штраф и, как ожидалось.