Loading a properties file from Java package - java

I need to read a properties files that's buried in my package structure in com.al.common.email.templates.
I've tried everything and I can't figure it out.
In the end, my code will be running in a servlet container, but I don't want to depend on the container for anything. I write JUnit test cases and it needs to work in both.

When loading the Properties from a Class in the package com.al.common.email.templates you can use
Properties prop = new Properties();
InputStream in = getClass().getResourceAsStream("foo.properties");
prop.load(in);
in.close();
(Add all the necessary exception handling).
If your class is not in that package, you need to aquire the InputStream slightly differently:
InputStream in =
getClass().getResourceAsStream("/com/al/common/email/templates/foo.properties");
Relative paths (those without a leading '/') in getResource()/getResourceAsStream() mean that the resource will be searched relative to the directory which represents the package the class is in.
Using java.lang.String.class.getResource("foo.txt") would search for the (inexistent) file /java/lang/String/foo.txt on the classpath.
Using an absolute path (one that starts with '/') means that the current package is ignored.

To add to Joachim Sauer's answer, if you ever need to do this in a static context, you can do something like the following:
static {
Properties prop = new Properties();
InputStream in = CurrentClassName.class.getResourceAsStream("foo.properties");
prop.load(in);
in.close()
}
(Exception handling elided, as before.)

The following two cases relate to loading a properties file from an example class named TestLoadProperties.
Case 1: Loading the properties file using ClassLoader
InputStream inputStream = TestLoadProperties.class.getClassLoader()
.getResourceAsStream("A.config");
properties.load(inputStream);
In this case the properties file must be in the root/src directory for successful loading.
Case 2: Loading the properties file without using ClassLoader
InputStream inputStream = getClass().getResourceAsStream("A.config");
properties.load(inputStream);
In this case the properties file must be in the same directory as the TestLoadProperties.class file for successful loading.
Note: TestLoadProperties.java and TestLoadProperties.class are two different files. The former, .java file, is usually found in a project's src/ directory, while the latter, .class file, is usually found in its bin/ directory.

public class Test{
static {
loadProperties();
}
static Properties prop;
private static void loadProperties() {
prop = new Properties();
InputStream in = Test.class
.getResourceAsStream("test.properties");
try {
prop.load(in);
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}

public class ReadPropertyDemo {
public static void main(String[] args) {
Properties properties = new Properties();
try {
properties.load(new FileInputStream(
"com/technicalkeeda/demo/application.properties"));
System.out.println("Domain :- " + properties.getProperty("domain"));
System.out.println("Website Age :- "
+ properties.getProperty("website_age"));
System.out.println("Founder :- " + properties.getProperty("founder"));
// Display all the values in the form of key value
for (String key : properties.stringPropertyNames()) {
String value = properties.getProperty(key);
System.out.println("Key:- " + key + "Value:- " + value);
}
} catch (IOException e) {
System.out.println("Exception Occurred" + e.getMessage());
}
}
}

Assuming your using the Properties class, via its load method, and I guess you are using the ClassLoader getResourceAsStream to get the input stream.
How are you passing in the name, it seems it should be in this form: /com/al/common/email/templates/foo.properties

I managed to solve this issue with this call
Properties props = PropertiesUtil.loadProperties("whatever.properties");
Extra, you have to put your whatever.properties file in /src/main/resources

Nobody mentions the similar but even simpler solution than above with no need to deal with the package of the class. Assuming myfile.properties is in the classpath.
Properties properties = new Properties();
InputStream in = ClassLoader.getSystemResourceAsStream("myfile.properties");
properties.load(in);
in.close();
Enjoy

use the below code please :
Properties p = new Properties();
StringBuffer path = new StringBuffer("com/al/common/email/templates/");
path.append("foo.properties");
InputStream fs = getClass().getClassLoader()
.getResourceAsStream(path.toString());
if(fs == null){
System.err.println("Unable to load the properties file");
}
else{
try{
p.load(fs);
}
catch (IOException e) {
e.printStackTrace();
}
}

Related

File does not exist in target/classes folder of JAR, meant to be read from resources project folder

I am trying to read. a config from my resources folder in Java project from my deployed code. I am able to read from my local laptop but after deployment as JAR .manifest file, it says path does not exist.
So my Java maven project str: src/main/java/.. and config path as follows:
Java code to read this config where file.exists() always returns false.
Trial 1: When config path is : src/main/resources/config.yaml.
File configPath = new File(Objects.requireNonNull(getClass().getClassLoader().getResource("config.yaml")).getFile());
if (!configPath.exists()) {
Log("ERROR", "Config file does not exist "); // this is printed
}
Trial 2: When config path is src/main/resources/feed/configs/config.yaml.
File dir = new File(Objects.requireNonNull(getClass().getClassLoader().getResource("feed/configs")).getFile());
if (!dir.exists()) {
Log("ERROR", "Config folder does not exist, "ERROR"); // THIS IS PRINTED
return;
}
File[] configFiles = configPath.listFiles(); // NOT EXECUTED AS ABOVE IS RETURNED
Since you have added the maven tag, I am assuming you are using maven.
As the .yaml is inside the resources folder you should be using getResourceAsStream()
/src/main/resources/config.yaml:
first: value1
second: value2
To read the file and its content:
import java.util.Properties;
import java.io.InputStream;
import java.io.IOException;
public class Example {
InputStream inputStream = null;
final Properties properties = new Properties();
public Example() {
try {
inputStream =
this.getClass().getClassLoader().getResourceAsStream("config.yaml");
properties.load(inputStream);
} catch (IOException exception) {
LOG("ERROR", "Config file does not exist ");
} finally {
if (inputStream != null){
try {
inputStream.close();
} catch (Exception e) {
LOG("ERROR", "Failed to close input stream");
}
}
}
}
public printValues(){
LOG("INFO", "First value is: " + properties.getProperty("first"));
}
}

File not found in a very basic project

I dont really understand why but I get file not found when I try to load the properties.
I put a file called c24.properties in the resources folder alongside with application.properties
private static final String PROP = "c24.properties";
private Properties properties;
// Constructor
public KTServices() {
try {
properties = new Properties();
properties.load(new FileInputStream(PROP)); // FILE NOT FOUND??
} catch (IOException e) {
e.printStackTrace();
}
}
Any help? Why it doesn't find? This is a Spring Boot maven project
PS: I just checked the /target and the c24.properties is in the root folder as expected
Properties appProps = new Properties();
try {
appProps.load(Thread.currentThread().getContextClassLoader().getResource("app.properties").openStream());
} catch (IOException var3) {
this.log.error("properties file not found", var3.toString());
}
return appProps;
If the file is in the same directory as the class file, you can use the following:
properties.load(KTServices.class.getResourceAsStream(PROP));
Any property files that are outside the jar requires a full path to locate successfully.

Call Property file from a jar included in my project

I´ve included a jar (I built it: MyJar.jar) that i use to authenticate, in that jar I have to read some properties that I have in a package (e.g com.myproject.properties) inside a property file of my project.
I have a method in MyJar.jar which receive the name of the property and the path for the property file something like this:
public String getValueOfProperty(String property,String pathToPropertyFile){
BasicTextEncryptor encryptor = new BasicTextEncryptor();
Properties props = new EncryptableProperties(encryptor);
props.load(new FileInputStream(pathToPropertyFile));
....
}
I got the following error: System can't find the specified path
The path is: com/myproject/properties/conf.properties
What am I doing wrong?
Solved,
This is what i Used:
The path the method receives is something like this: /sv/com/myproject/configuration/file.properties,
This method will search with relative path
public String decryptVar(String var,String PathPropertyFile) throws Exception{
try {
BasicTextEncryptor encryptor = new BasicTextEncryptor();
Properties props = new EncryptableProperties(encryptor);
InputStream fis = this.getClass().getResourceAsStream(PathPropertyFile);
props.load(fis);
encryptor.setPassword(props.getProperty("PROPERTY_IN_FILE"));
return props.getProperty(var);
} catch (Exception e) {
throw new Exception(e.getMessage());
}
}
Implementing: JASYPTH

Reference properties file outside src directory

If I have the following directory structure,
+src
++com.foo.util
+++FooProperties.java
+foo.properties
How do I reference foo.properties as a resource stream in FooProperties? I've tried adding it to the classpath and referencing it as such,
FooProperties.class.getResourceAsStream("/foo.properties")
but I get a NullPointerException. What am I doing wrong?
If you want to keep the properties file outside the src(same level as src), then you can fetch your properties file this way:-
try {
InputStream fileStream = new FileInputStream(new File(
"test.properties"));
Properties props = new Properties();
props.load(fileStream);
String myPropValue = (String) props.get("test.prop");
System.out.println(myPropValue);
} catch (FileNotFoundException e) {
} catch (IOException e) {
}
Hope it helps. You can even edit the properties file using the above method(no absolute path required).

getSystemResourceAsStream() returns null

Hiii...
I want to get the content of properties file into InputStream class object using getSystemResourceAsStream(). I have built the sample code. It works well using main() method,but when i deploy the project and run on the server, properties file path cannot obtained ... so inputstream object store null value.
Sample code is here..
public class ReadPropertyFromFile {
public static Logger logger = Logger.getLogger(ReadPropertyFromFile.class);
public static String readProperty(String fileName, String propertyName) {
String value = null;
try {
//fileName = "api.properties";
//propertyName = "api_loginid";
System.out.println("11111111...In the read proprty file.....");
// ClassLoader loader = ClassLoader.getSystemClassLoader();
InputStream inStream = ClassLoader.getSystemResourceAsStream(fileName);
System.out.println("In the read proprty file.....");
System.out.println("File Name :" + fileName);
System.out.println("instream = "+inStream);
Properties prop = new Properties();
try {
prop.load(inStream);
value = prop.getProperty(propertyName);
} catch (Exception e) {
logger.warn("Error occured while reading property " + propertyName + " = ", e);
return null;
}
} catch (Exception e) {
System.out.println("Exception = " + e);
}
return value;
}
public static void main(String args[]) {
System.out.println("prop value = " + ReadPropertyFromFile.readProperty("api.properties", "api_loginid"));
}
}
i deploy the project and run on the server,
This sounds like a JSP/Servlet webapplication. In that case, you need to use the ClassLoader which is obtained as follows:
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
This one has access to the all classpath paths tied to the webapplication in question and you're not anymore dependent on which parent classloader (a webapp has more than one!) has loaded your class.
Then, on this classloader, you need to just call getResourceAsStream() to get a classpath resource as stream, not the getSystemResourceAsStream() which is dependent on how the webapplication is started. You don't want to be dependent on that as well since you have no control over it at external hosting:
InputStream input = classLoader.getResourceAsStream("filename.extension");
This is finally more robust than your initial getSystemResourceAsStream() approach and the Class#getResourceAsStream() as suggested by others.
The SystemClassLoader loads resources from java.class.path witch maps to the system variable CLASSPATH. In your local application, you probably have the resource your trying to load configured in java.class.path variable. In the server, it's another story because most probably the server loads your resources from another class loader.
Try using the ClassLoader that loaded class using the correct path:
getClass().getResourceAsStream(fileName);
This article might also be useful.
Try using getResourceAsStream() instead of getSystemResourceAsStream().

Categories

Resources