Resources and config loading in maven project

霸气de小男生 提交于 2019-12-03 15:20:55

I think I found the solution. As Juned Ahsan and mR_fr0g write, I need to use ClassLoader class, instead of this.getClass().getResource(). But, it works only for resource folder. But maven allows to add other folders as resource folders. I was just needed to add this section to pom.xml:

<build>
    <resources>
        <resource>
            <directory>src/main/config</directory>
        </resource>
    </resources>
</build>

And working java code is:

InputStream image = this.getClass().getClassLoader().getResourceAsStream("images/image.png");
InputStream config = ClassLoader.getSystemResourceAsStream("config.xml");

You can use getResourceAsStream() method of java.lang.Class as you have done, but you have to add / before the path.


This question is tricky.

1. Two methods with same name

First of all, exist two methods of same name and same signature in these two classes:

java.lang.Class
java.lang.ClassLoader

They have the same name: getResource(String) (and getResourceAsStream(String) is alike).

2. They accept params of different format

Then, the param of them has different format:

  • The method java.lang.Class.getResouce<asStream>() accepts path with and without the leading /, resulting in different resources searching strategies. If a path has no /, Java will search the resource in the package/folder where the .class file resides. If it has /, Java will begin the searching from classpath root.
  • The method java.lang.ClassLoader.getResource<asStream>() accepts only path without /, because it always search from classpath. In a classpath based path, / is not a valid character. *

    *: As this answer states: this.getClass().getClassLoader().getResource("...") and NullPointerException

How to add a folder to classpath? In Eclipse we resolve to the context menu of a project: "Build path" - "Configure build path..." and add some folder to build path.

3. When it comes to Maven

At last, if a project is a Maven project, by default src/main/resources is in the classpath, so we can use

Class.getResource("/path-to-your-res");

or,

ClassLoader.getResource("path-to-your-res");

, to load anything under src/main/resources.

If we want to add another resources folder, as you have mentioned, it is done in pom.xml. And they are added into classpath as well, done by Maven. No extra config is needed.

4. Example

For example, if your config.ini is under src/main/resources/settings, myAvatar.gif under src/main/images, you can do:

In pom.xml:

<build>
    <resources>
        <resource>
            <directory>src/main/images</directory>
        </resource>
    </resources>
</build>

In code:

URL urlConfig = MyClass.class.getResource("/settings/config.ini"); //by default "src/main/resources/" is in classpath and no config needs to be changed.
InputStream inputAvatar = MyClass.class.getResourceAsStream("/myAvatar.gif"); //with changes in pom.xml now "src/main/images" is counted as resource folder, and added to classpath. So we use it directly.

We must use / above.

Or, with ClassLoader:

URL urlConfig = MyClass.class.getClassLoader().getResource("settings/config.ini"); //no leading "/"!!!
InputStream inputAvatar = MyClass.class.getClassLoader().getResourceAsStream("myAvatar.gif"); //no leading "/"!!!
public Preferences() {
    InputStream image = this.getClass().getClassLoader().getResourceAsStream("image.png");
    InputStream config = this.getClass().getClassLoader().getResourceAsStream("config.xml")
} 

How about using this appraoch:

InputStream file = ClassLoader.getSystemResourceAsStream("res.txt");

or

InputStream file = Thread.currentThread().getContextClassLoader().getResourceAsStream("MyProperty.properties");

As you currently have it there, that will look for the MyProperty.properties file at the top of your classpath. The could be in your src/main/resources directory or other src folder -- it would depend on how your application (jar/war) is built.

If you are building a jar then you should be able to unpack it and see your properties file at the top level of the jar. If you are building a war, maybe it should be in the WEB-INF/classes directory. Again, it depends on how it was built.

Try to build the project before. If you just put the files in the resources folder then you need to build the project in order to copy the new resource files into target folder

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!