Resources and config loading in maven project
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.
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 "/"!!!
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");