从外部模块使用类加载资源文件

huangapple go评论62阅读模式
英文:

Loading resource file from external module using Class

问题

我在尝试从外部模块的资源文件夹加载资源文件时遇到了困难。我正在使用IntelliJ,我们的项目是使用Maven构建的。

在使用模块之前的原始代码如下:

getClass().getResourceAsStream(rulesFile)

现在这会导致结果为null


模块的结构如下:

client
    - java
        - org.example.client
            - Controller.java

data
    - java
        - ...
    - resources
        - org.example.data.files
            - rulesFile

client模块中:

getClass().getResourceAsStream(rulesFile)不起作用。

然而,如果我尝试这样做 ModuleLayer.boot().findModule("data").get().getResourceAsStream(rulesFile),那么它就能正常工作。

我的问题是,是否可能使rulesFileclient模块内的Controller.java可见,以便可以使用普通的类加载器?我希望避免不得不显式地指定它来自哪个模块,因为从data模块加载文件的类似代码在其他地方也被使用。

我有什么选项可以避免必须显式地提供模块名称?

我已经尝试将以下内容添加到data模块文件中,但没有成功:

opens org.example.data.files to client

谢谢帮助!

英文:

I'm having difficulty trying to load a resource file from an external module's resource folder. I am using IntelliJ and our project is built using Maven.

The original code, prior to using modules was as such:

getClass().getResourceAsStream(rulesFile)

This now results in a null result.


The structure of the modules is as such:

client
    - java
        - org.example.client
            - Controller.java

data
    - java
        - ...
    - resources
        - org.example.data.files
            - rulesFile

In module client:

getClass().getResourceAsStream(rulesFile) does not work.

However, if I try and do ModuleLayer.boot().findModule("data").get().getResourceAsStream(rulesFile), then it works fine.

My question is, is it possible to make the rulesFile visible to the Controller.java inside the client module so that a normal class loader can be used? I would like to avoid having to explicitly specify the module name it is coming from as similar code to load files from the data module is used elsewhere.

What options do I have to avoid having to explicitly giving the module name?

I have tried adding the following to the data module file, with no success:

opens org.example.data.files to client

Thanks for the help!

答案1

得分: 2

<project>
	...

	<build>
		...

		<resources>
			<resource>
				<directory>../data/src/main/resources/org/example/data/files</directory>
				<includes>
					<include>rulesFile</include>
				</includes>
			</resource>
		</resources>
	</build>
</project>
英文:

http://maven.apache.org/pom.html#Resources

add in your client module pom.xml:

<project>
	...

	<build>
	...

		<resources>
			<resource>
				<directory>../data/src/main/resources/org/example/data/files</directory>
				<includes>
					<include>rulesFile</include>
				</includes>
			</resource>
		</resources>
	</build>
</project>

答案2

得分: 0

以下是翻译好的内容:

模块的结构如下:

客户端 (client)
    - Java
        - org.example.client
            - Controller.java

数据 (data)
    - Java
        - Data.java
    - 资源 (resources)
        - org.example.data.files
            - rulesFile

暂时来说,也许不是最理想的解决方案,但似乎你可以在从 data 模块内的 Class 中工作时从 data 模块加载。

还需要注意的是,我已经将 data 资源文件夹也开放给了 client 模块。

与其尝试像这样:

Controller.class.getResourceAsStream(rulesFile)

如果你这样做:

Data.class.getResourceAsStream(rulesFile) 它能正常工作,这是因为 Data.java 位于 data 模块内,而 rulesFile 也在其中。

英文:

The structure of the modules is as such:

client
    - java
        - org.example.client
            - Controller.java

data
    - java
        - Data.java
    - resources
        - org.example.data.files
            - rulesFile

For now, maybe not the most ideal solution, but it seems that you can load from the data module when working from a Class inside the data module.

It is also important to note I have opened the data resources folder to the client module as well.

Rather than trying something like:

Controller.class.getResourceAsStream(rulesFile)

If you do:

Data.class.getResourceAsStream(rulesFile) it works, this is because Data.java is inside the data module, where the rulesFile resides.

答案3

得分: 0

在Java的.ear类型的包装构件中,同样会出现需要在一个模块的类路径中包含另一个模块的情况。在这种情况下,将所需的模块标记为“想要的”模块的依赖项,应该会将它并入“想要的”模块的类路径中。具体来说,在ear中的wars需要访问ear中的ejbs时会发生这种情况。

您只需按构件名称将该模块添加到“想要的”模块的pom.xml文件的依赖项部分中:

<dependencies>
  <dependency>
    <artifactId>data</artifactId>
  </dependency>
</dependencies>

构件的其他属性由Maven中的父POM文件推断出来,因此您无需提及versiongroupId。范围可以指定为runtime,但我认为这可能是默认值。

如果一切顺利,您应该能够使用getClass().getResourceAsStream(rulesFile)来完成。

英文:

In a Java .ear type package artifact, this also happens where you need the classpath of one module to include another module. In that case, marking the necessary module as a dependency in the "wanting" module should incorporate it into the classpath of the
"wanter". Specifically, this occurs with wars needing to access ejbs in an ear.

You would add the module simply by artifact name to the dependency section of the "wanting" module's pom.xml:

&lt;dependencies&gt;
  &lt;dependency&gt;
    &lt;artifactId&gt;data&lt;/artifactId&gt;
  &lt;/dependency&gt;
&lt;/dependencies

The other attributes of the artifact are inferred by your parent pom in Maven so you don't need to mention version, or groupId. Scope could be cited as runtime but I think that may be default anyway.

If all goes well, you should be able to just do getClass().getResourceAsStream(rulesFile).

huangapple
  • 本文由 发表于 2020年10月12日 01:47:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/64307216.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定