Following scenario
./
config/
application.properties
lib/
properties-loader-0.0.1-SNAPSHOT.jar
acme.sh
properties-loader-0.0.1-SNAPSHOT.jar
is an executable jar with a manifest file.
There is one package com.acme.lab
within the jar, containing only the class
with the fully qualified name com.acme.lab.PropertiesLoader
.
The script acme.sh
executes the following command:
java -cp etc/application.properties:./lib/properties-loader-0.0.1-SNAPSHOT.jar com.acme.lab.PropertiesLoader
I'm trying to access the properties file from the PropertiesLoader
class. I read the article Smartly load your properties but still have problems to access the properties file
System.out.println(this.getClass().getResourceAsStream("../etc/application.properties"));
System.out.println(this.getClass().getResourceAsStream("etc/application.properties"));
System.out.println(this.getClass().getResourceAsStream("/etc/application.properties"));
System.out.println(this.getClass().getResourceAsStream("application.properties"));
System.out.println(this.getClass().getClassLoader().getResourceAsStream("../etc/application.properties"));
System.out.println(this.getClass().getClassLoader().getResourceAsStream("etc/application.properties"));
System.out.println(this.getClass().getClassLoader().getResourceAsStream("/etc/application.properties"));
System.out.println(this.getClass().getClassLoader().getResourceAsStream("application.properties"));
try {
System.out.println(ResourceBundle.getBundle("etc.application"));
System.out.println(ResourceBundle.getBundle("application"));
} catch(MissingResourceException e) {
// do nothing
}
All these calls fail to load the file.
I just know that the error has something to do with the classpath, but can't seem to find it. I created a sample maven project on github that recreates the problem.
Resources are interpreted from their classpath roots. Which in your case when you run your program like this:
java -cp etc/application.properties:./lib/properties-loader-0.0.1-SNAPSHOT.jar
The roots are
./etc/application.properties
./lib/properties-loader-0.0.1-SNAPSHOT.jar
Neither of which contains your application.properties file (as a sub-resource). If you modified your command like this:
java -cp etc:./lib/properties-loader-0.0.1-SNAPSHOT.jar
Then you could read your properties file in your program as:
Thread.currentThread().getContextClassLoader().getResourceAsStream("application.properties");
As a side note, its always best to use fully qualified paths in your classpath setting.
* EDIT *
This is a working example that should illustrate resource loading:
mkdir props; cd props
mkdir etc; touch etc/application.properties
mkdir test; vi test/PropLoader.java
Paste this content into the editor then save:
package test;
import java.io.InputStream;
public class PropLoader {
public static void main(String[] args) {
try {
final String path;
if(args.length == 1) path = args[0].trim();
else path = "etc/application.properties";
final InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(path);
if(is == null) throw new RuntimeException("Failed to load " + path + " as a resource");
else System.out.printf("Loaded resource from path: %s\n", path);
} catch(Exception e) {
e.printStackTrace();
}
}
}
And to test:
javac test/PropLoader.java
java -cp . test.PropLoader
Output is Loaded resource from path: etc/application.properties
.