如何从多个项目访问公共资源文件

时间:2014-01-23 17:40:09

标签: java maven resources dbunit

在我的一个项目中,我将资源存储在/src/test/resources(典型的maven目录结构)中。这些资源正由项目中存储的实用程序类使用。

实用程序类本身正在从其他项目中使用(其他项目依赖于此项目)。我会像这样访问资源:

final InputStream inputStreamDobs = 
    ClassLoader.class.getResourceAsStream("/dbunit/clear_db.xml");

但是因为我在不同的项目中使用它的路径不正确 - 它相对于current project that is being built/tested,而不是实用程序类和资源所在的那个。

有人想过如何处理这个问题吗?

我需要避免绝对路径 - 希望有一种方法来定义实用程序类的相对路径。

我也不想在多个项目上复制资源。欢呼声。

修改 为了给出一个上下文,我有一个XML文件中的表的定义,需要在集成测试后清除(清除整个数据库模式)。集成测试位于多个项目中,但清晰的脚本和资源文件对于所有项目都是相同的,并且位于公共父项目中。

EDIT2:

加分问题:我想访问需要从多个其他项目的XML文件访问的常见DTD文件(让我们称之为tables.dtd)。 (它将位于共同的父项目中。)

目前我将它复制到多个项目中,我使用指令从XML引用它:

<!DOCTYPE dataset SYSTEM "src/test/resources/dbunit/dobs.dtd">

如何将其指向不同项目中的文件?

8 个答案:

答案 0 :(得分:6)

您的运行时类路径不应引用src / test / resources。 Maven会将所有内容复制到目标,因此您应该可以使用“/dbunit/clear_db.xml”获取它

答案 1 :(得分:6)

你写了

  

...但是因为我在不同的项目中使用它的路径不正确 - 它与正在构建/测试的当前项目相关,而不是与实用程序类和资源相关的项目。   ...

相对路径不是问题。在示例中使用绝对路径,但即使您使用相对路径,也会引用包或目录结构。只要类路径正确,getResourceAsStream就会接收它们。真正的问题是您在另一个项目中引用了 测试资源 。但是测试资源和类不包含在项目工件中,因此无法从包含此作为依赖项的模块访问它们。如果您需要这些资源用于多个项目中的测试,我建议您使用src/main/resources中包含的这些资源创建一个新项目(假设为“projectxyz-testresources”),并将其添加为范围为“test”的依赖项相关的。

已编辑添加:

如果您不想为测试资源使用单独的项目,可以使用目标jar:test-jar创建包含测试类和资源的测试jar,并将其作为测试依赖项包含在内。您可能希望在pom中配置jar插件以在常规构建上执行此目标。

答案 2 :(得分:3)

您是否尝试过使用“classpath:”前缀?如果类路径上有资源,则不必指定资源的完整路径。例如:

<mvc:resources location="classpath:/META-INF/web-resources/" mapping="/resources/**" />

/ META-INF / web-resources /来自Spring MVC的JAR,它是项目的依赖项之一。该项目不需要知道如何“直接”获取该资源,而是使用类路径。

答案 3 :(得分:3)

我认为您可以使用以下2个插件来实现此目的。 如果您的项目是Web项目,您可以创建2个Web项目,其中一个包含配置文件,另一个项目是您的主项目,现在您可以使用maven-war-plugin覆盖项目

有多种类型的叠加,您可以访问此页面以获取更多信息 maven-war-plugin overlay

对于jar文件,您可以将它们合并到maven-assembly-plugin

的单个文件中

maven-assembly-plugin

答案 4 :(得分:3)

我们有一个类似的实例,其中有一些配置文件用于大型多模块maven项目中的多个模块。 所以我们所做的就是将conf文件拆分成一个单独的模块,只是简化了配置文件。 然后,无论需要哪些模块,这些文件都可以声明对配置文件模块的依赖性,只需将jar文件与配置文件一起使用并解压缩即可使用它们。 你可以为测试资源做类似的事情。创建一个只包含资源的模块,然后将它们放入相关路径。

答案 5 :(得分:2)

在这种情况下,我建议为此任务编写maven插件,以便可以通过属性配置这么可变的路径。 您还将受益于Project对象。

/**
 * Location of the file.
 */
@Parameter(defaultValue = "${basedir}/src/main/java", property = "sourceFolder", required = true)
private File sourceFolder;

@Parameter(defaultValue = "${basedir}/src/test/java", property = "testFolder", required = true)
private File testFolder;

@Parameter(defaultValue = "${project}", property = "project", readonly = true, required = true)
private MavenProject project;

答案 6 :(得分:2)

您可以尝试使用Maven Overlays吗?我们过去曾遇到过类似的情况,并且使用叠加层解决了很多问题。通常,覆盖用于跨多个Web应用程序共享公共资源。

答案 7 :(得分:2)

可能是其中一种方法:

要么:将xml文件和需要访问它们的java类(如实用程序类)外包到一个单独的库中,然后可以将其包含在其他几个项目中(方便地作为maven依赖项)。

或者:您将这些xml文件放入单独的VCS树或存储库中,并将它们包含在项目树中(例如,作为SVN中的“外部”)。因此,您可以在项目中单独更新此引用,但只需维护一个源文件。