2011-03-13 77 views
20

在我的Maven项目中,有一个模块(核心)有几个类的资源。在模块内部运行类时,它可以获得自己的资源。一切正常。使用依赖关系的资源?

其中的东西中断是依赖于内核的另一个模块试图运行该类。 Java正在寻找资源的文件夹是此模块,而不是核心模块。所以班级失败了。

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


我已经试验,试图通过在核心的JAR清单Class-Path: .声明来做到这一点。然而上市可用的资源时JSHookLoader.class.getClassLoader().getResources("");(JSHookLoader是核心,如果这意味着什么),我得到:

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本身是在类路径复杂的事情,而不是目录JAR在

有什么建议吗?


回到这个项目我仍然有这个问题。其他指南已经讨论过使用maven-assembly-plugin和远程资源插件,但是所有模块都必须包含怪物插件XML,这是非常痛苦的。

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

  1. core.jar在文件夹/资源下面有一些资源。运行core.jar我可以看到资源列表中的资源。
  2. impl.jar依赖于core.jar。一旦运行它/资源不在资源列表中,因此会造成严重破坏。

这应该很简单,但我该怎么做呢?我花了几个小时试图找出一个简单的干净的方式来做到这一点,但无济于事。

回答

21

经过大量的搜索在一个解决方案,我终于迷迷糊糊的。

我的解决方案采用了核心模块,并使用Maven Dependency Plugin解压缩它,确保排除META-INF文件夹和编译类所在的组织文件夹。我排除我不想要的东西,而不是明确地说明我所需要的是,可以轻松添加新资源,而无需我一直更新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> 
+0

返回的结果感谢您发布您的解决方案!我有这个确切的问题,并找到了答案......但它是用maven术语写的,我正在努力破译它。 – CaffiendFrog 2014-01-28 23:06:05

+1

使用此时请注意循环依赖关系。您可能会遇到困难。 – Michael 2017-12-04 17:47:30

3

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

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

+0

请参阅我的问题中的更新,它不会像您所说的那样工作。 – TheLQ 2011-03-13 23:11:19

0

我不认为这是一个好主意。假设你有模块A。它取决于'B'。 'B'取决于C。基本上,只关于B模块的接口A。也许,明天 它将依赖性从C更改为D。如果发生这种情况,您需要更改A。这不是很好的情况,是吗?所以用隐含的方式声明来自C的相关A

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

总之:直接声明这种依赖性。

+0

它被直接声明。我所说的模块直接取决于Core。 – TheLQ 2011-03-13 21:58:13

1

如果你的依赖JAR有一类名为OneDependent,那么这应该工作:

OneDependent.class.getResourceAsStream(resourcePath) 
+0

这就是我所做的。它只显示了Core JAR所在的目录,而不是它的内容。 – TheLQ 2011-03-15 13:27:25

+0

试图了解你在说什么目录... getResourceAsStream()调用要么给你一个资源,要么是null,如果它找不到资源。你的情况回报是什么? – 2011-03-16 06:03:10

+1

回复了JSHookLoader.class.getClassLoader()。getResources(“”);' – TheLQ 2011-03-16 20:30:21

0

我也有类似的情况刚才什么的副本。我有一个“测试代码生成器”,它从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> 

到moduleB的构建部分,现在通过构建罚款,如预期运行。