I'm using Maven for desktop applycation. I read about Maven standart directory layout and I have this project structure for now:
App
|-- pom.xml
`-- src
|-- main
|-- java
| `-- java classes
|-- resources
| `-- images
| `-- app images
`--config
`--config.xml
I want to find a way to load my resources and config files. I read some articles and topics and found this (simplified example from my code):
//class for loading config
public class Preferences {
public Preferences() {
InputStream image = Preferences.class.getResourceAsStream("images/image.png");
InputStream config = Preferences.class.getResourceAsStream("config.xml");
}
}
But image and config variables contains null. I was trying different variants of loading (from root folder, with this.getClass() instead of Preferences.class, and others), but I always have null. I really don't understand this resource loading system and I didn't find any good documentation about it. It would be nice, if somebody gives a good explanation about this mechanism (or just give a link on docs). So, the main question is: How can I load my resources and config files?
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.
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).
Then, the param of them has different format:
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.
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.
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 "/"!!!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With