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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21315549/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 08:00:17  来源:igfitidea点击:

How to access common resource files from multiple projects

javamavenresourcesdbunit

提问by FazoM

In one of my projects I have resources stored in /src/test/resources(typical maven directory structure). Those resources are being used by an utility class stored in the project.

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

The utility class itself is being used from other projects (other projects depend on this one). I would access the resource like that:

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

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

but since I use it from different projects the path is not correct - it is relative to current project that is being built/tested, not the one where utility class and resources are.

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

Any thought how to approach this?

任何想法如何解决这个问题?

I need to avoid absolute paths - would like to have a way of defining relative path to the utility class.

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

I also don't want to replicate resources over multiple projects. Cheers.

我也不想在多个项目上复制资源。干杯。

EDIT:To give a context I have a definition of tables in XML file that needs to be cleared after Integration Tests (clear whole DB schema). Integration Tests sits in multiple project, but the clear script and resource file is the same for all of them and sits in common parent project.

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

EDIT2:

编辑2:

Bonus question:I would like to access common DTD file (let's call it tables.dtd) that need to be accessed from XML files from multiple other projects. (it will sit in common parent project).

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

Currently I have it duplicated over multiple project, and I refer to it from XML using directive:

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

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

How to point it to a file in different project?

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

采纳答案by Drunix

You wrote

你写了

... but since I use it from different projects the path is not correct - it is relative to current project that is being built/tested, not the one where utility class and resources are ...

...但由于我从不同的项目中使用它,路径不正确 - 它相对于正在构建/测试的当前项目,而不是实用程序类和资源所在的项目......

Relative paths are not the problem here. You use an absolute path in your example, but even if you would use a relative one, this would refer to the package or directory structure. getResourceAsStreamwould pick them up as long as the classpath is correct. The real problem is that you are referring to test resourcesin another project. But test resources and classes are not contained in the project artifact, so they are not accessible from modules that include this as a dependency. If you need these resources for tests in several projects, I would suggest that you create a new project (let's say "projectxyz-testresources") with these resouces contained in src/main/resourcesand add this as a dependency with scope "test" where relevant.

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

EDITED TO ADD:

编辑添加:

If you don't want to use a separate project for test resources, you can create a test-jar containing test classes and resources using goal jar:test-jarand include this as a test dependency. You may want to configure the jar plugin in your pom to execute this goal on regular builds.

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

回答by evanchooly

Your runtime classpath shouldn't reference src/test/resources. Maven will copy everything over to target so you should be able to get it with "/dbunit/clear_db.xml"

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

回答by Hannes

In this case, I would suggest to program a maven plugin for this task, so that this so variable path may be configured via properties. You will also benefit from the Project object.

在这种情况下,我建议为此任务编写一个 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;

回答by farmbytes

Can you try using Maven Overlays? We had faced similar situation in the past, and very much resolved using overlays. Usually, overlays are used to share common resources across multiple web applications.

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

回答by thomas.mc.work

Maybe one of these approaches:

也许这些方法之一:

Either: You outsource the xml files AND the java classes (like the utility class) that need access to them into a seperate library which you can then include into your several other projects (conveniently as maven dependencies).

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

Or: You put these xml files into a seperate VCS-tree or repository and you include them in your project tree (e.g. as an "external" in SVN). So you can update this reference seperately in your projects, but you only have to maintain one source file.

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

回答by SergeyB

Have you tried using "classpath:" prefix? You shouldn't have to specify full paths to resources if they are available on the classpath. For example:

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

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

/META-INF/web-resources/ comes from Spring MVC's JAR which is one of the project's dependencies. The project doesn't need to know how to get to that resource "directly" instead it uses the classpath.

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

回答by Ashkan

I think you can use 2 below plugins for this purpose. if your project is web project, you can create 2 web projects, one of them contains config files and another project is your main project, now on you can overlay projects with maven-war-plugin

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

There are many types for overlay, you can visit this page for more information maven-war-plugin overlay

叠加的类型很多,您可以访问此页面了解更多信息 maven-war-plugin 叠加

for jar files you can merge them to single one with maven-assembly-plugin

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

maven-assembly-plugin

Maven 程序集插件

回答by Yogesh_D

We had a similar instance in which, we had some configuration files that were used across multiple modules in big multi module maven project. So what we did was split the conf files into a separate module, that just jars up the config files. And then whatever module needed those files could declare the dependency to the config files modules and just use the jar files with the config files and unzip them to use them. You could do something similar for the test resources. Create a module with just the resources and then put them into the relevant path.

我们有一个类似的实例,其中我们有一些配置文件在大型多模块 maven 项目中跨多个模块使用。所以我们所做的是将 conf 文件拆分为一个单独的模块,这只是将配置文件打包。然后,任何需要这些文件的模块都可以声明对配置文件模块的依赖关系,只需将 jar 文件与配置文件一起使用,然后解压缩即可使用它们。您可以对测试资源执行类似的操作。创建一个仅包含资源的模块,然后将它们放入相关路径。