使用依赖项的资源?

时间:2011-03-13 20:48:17

标签: java maven

在我的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。

为什么我不简化问题:如何将依赖JAR添加到资源列表?

  1. core.jar在文件夹/ resources下有一些资源。运行core.jar我可以在资源列表中看到/ resources。
  2. impl.jar取决于core.jar。运行它/资源不在资源列表中,因此造成破坏。
  3. 这应该很简单,但我该怎么做呢?我花了好几个小时试图想出一个简单干净的方法去做,但无济于事。

5 个答案:

答案 0 :(得分:31)

经过大量搜索,我终于找到了解决方案。

我的解决方案采用核心模块并使用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> 

答案 1 :(得分:6)

如果资源位于JAR中的/src/main/resources 类中,则使用getResourceAsStream()访问它们,您应该能够从其他JAR中的类访问这些文件好吧(也使用getResourceAsStream())。这是因为/src/main/resources中的所有文件最终都位于同一逻辑目录(CLASSPATH)中。换句话说:位于/src/main/resources的所有文件和从/src/main/java编译的所有类都可以说合并到一个命名空间中。

如果您仍然无法访问文件,即使所有类都使用统一的getResourceAsStream() API,您可能会遇到一些类加载可见性问题。

答案 2 :(得分:1)

如果您的从属JAR有一个名为OneDependent的类,那么这应该有效:

OneDependent.class.getResourceAsStream(resourcePath)

答案 3 :(得分:0)

我认为这不是一个好主意。假设您有模块A。它取决于'B'。 'B'取决于C。基本上,您应该只关注A模块的接口B。也许,明天 它改变了从CD的依赖关系。如果发生这种情况,您将需要更改A。这不是好情况,是吗?因此,以隐式方式从A声明依赖C

  

简而言之:我如何访问依赖项的资源?

简而言之:直接宣告这种依赖。

答案 4 :(得分:0)

我刚才有类似的情况。我有一个&#34;测试代码构建器&#34;从src / test / resources目录获取数据并将数据泵入H2数据库。从模块A可以正常工作,但是当从模块B调用它时它没有。它构造一个具有多个分号的路径(由于资源在jar文件中);然后,moduleA无法找到文件&#34;本地和#34;。

最后,我添加了

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

到moduleB的构建部分,现在构建运行正常并且符合预期。