Использовать ресурсы зависимости? - PullRequest
28 голосов
/ 13 марта 2011

В моем проекте 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-plugin и плагина удаленных ресурсов, но это большая боль, так как все модули должны включать XML-плагин monster.

Почему бы не упростить вопрос до этого: Как я могу добавить JAR-файл зависимостей в список ресурсов?

  1. core.jar содержит некоторые ресурсы в папке / resources. Запустив core.jar, я вижу / resources в списке ресурсов.
  2. impl.jar зависит от core.jar. Однако после запуска / resources его нет в списке ресурсов, что приводит к хаосу.

Это должно быть достаточно просто, но как я могу это сделать? Я часами пытался найти простой способ сделать это, но безрезультатно.

Ответы [ 5 ]

31 голосов
/ 23 июня 2011

После долгих поисков я, наконец, наткнулся на решение.

Мое решение берет основной модуль и распаковывает его с помощью подключаемого модуля Maven Dependency Plugin, исключая папку META-INF и папку org, в которой находятся скомпилированные классы. Причина, по которой я исключаю то, что я не хочу, вместо того, чтобы явно указывать, что я хочу, заключается в том, что новые ресурсы могут быть легко добавлены без необходимости постоянно обновлять POM.

Причина, по которой я не использую плагин сборки или плагин удаленных ресурсов, заключается в том, что они используют выделенные модули ресурсов. Я не думаю, что мне нужно создавать модуль ядра и модуль ресурсов ядра, а модуль ресурсов ядра содержит только файлы конфигурации logback и hibernate + некоторые другие вещи.

Вот копия того, что я использую для этого

    <build>
        <plugins>
            <!--Extract core's 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> 
6 голосов
/ 14 марта 2011

Если ресурсы расположены в /src/main/resources и классы в JAR обращаются к ним с помощью getResourceAsStream(), вы должны иметь возможность доступа к этим файлам из классов в других JAR-файлах. также (также используя getResourceAsStream()). Это связано с тем, что все файлы, расположенные в /src/main/resources, в конечном итоге попадают в один и тот же логический каталог (CLASSPATH). Другими словами: все файлы, расположенные в /src/main/resources, и все классы, скомпилированные из /src/main/java, так сказать, объединены в одно пространство имен.

Если вы все еще не можете получить доступ к файлам, даже если все классы используют единый getResourceAsStream() API, у вас могут возникнуть некоторые проблемы с видимостью при загрузке классов.

1 голос
/ 14 марта 2011

Если у вашего зависимого JAR есть класс с именем OneDependent, то это должно работать:

OneDependent.class.getResourceAsStream(resourcePath)
0 голосов
/ 09 августа 2017

У меня была похожая ситуация только сейчас. У меня есть «построитель тестового кода», который берет данные из каталога src / test / resources и закачивает данные в базу данных H2. Работает нормально из модуля A, но при вызове из модуля B это не так. Он создает путь с несколькими точками с запятой (из-за ресурсов, находящихся в файле jar); Затем модуль A не может найти файлы, "локальные для себя".

В итоге я добавил

    <testResources>
        <testResource>
            <directory>src/test/resources</directory>
        </testResource>
        <testResource>
            <directory>../moduleA/src/test/resources</directory>
        </testResource>
    </testResources>

к разделу сборки moduleB, и теперь сборка проходит нормально и, как и ожидалось.

0 голосов
/ 14 марта 2011

Не думаю, что это хорошая идея. Предположим, у вас есть модуль A. Это зависит от «B». «B» зависит от C. В принципе, вы должны заботиться только о A интерфейсе модуля B. Возможно завтра это меняет зависимость от C до D. Если это произойдет, вам нужно изменить A. Это не хорошая ситуация, не так ли? Поэтому объявляем зависимость A от C неявным образом.

Вкратце: как я могу получить доступ к ресурсам зависимости?

Вкратце: объявите эту зависимость напрямую.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...