Reading Properties file in Java - java

I have the following code trying to read a properties file:
Properties prop = new Properties();
ClassLoader loader = Thread.currentThread().getContextClassLoader();
InputStream stream = loader.getResourceAsStream("myProp.properties");
prop.load(stream);
I get an exception at the last line. Specifically:
Exception in thread "main" java.lang.NullPointerException
at java.util.Properties$LineReader.readLine(Properties.java:418)
at java.util.Properties.load0(Properties.java:337)
at java.util.Properties.load(Properties.java:325)
at Assignment1.BaseStation.readPropertyFile(BaseStation.java:46)
at Assignment1.BaseStation.main(BaseStation.java:87)
thanks,
Nikos

Based on your exception, the InputStream is null, this means the class loader is not finding your properties file. I'm guessing that myProp.properties is in the root of your project, if that's the case, you need a preceding slash:
InputStream stream = loader.getResourceAsStream("/myProp.properties");

You can find information on this page:
http://www.mkyong.com/java/java-properties-file-examples/
Properties prop = new Properties();
try {
//load a properties file from class path, inside static method
prop.load(App.class.getClassLoader().getResourceAsStream("config.properties"));
//get the property value and print it out
System.out.println(prop.getProperty("database"));
System.out.println(prop.getProperty("dbuser"));
System.out.println(prop.getProperty("dbpassword"));
}
catch (IOException ex) {
ex.printStackTrace();
}

You can use ResourceBundle class to read the properties file.
ResourceBundle rb = ResourceBundle.getBundle("myProp.properties");

Properties prop = new Properties();
try {
prop.load(new FileInputStream("conf/filename.properties"));
} catch (IOException e) {
e.printStackTrace();
}
conf/filename.properties base on project root dir

You can't use this keyword like -
props.load(this.getClass().getResourceAsStream("myProps.properties"));
in a static context.
The best thing would be to get hold of application context like -
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:/META-INF/spring/app-context.xml");
then you can load the resource file from the classpath -
//load a properties file from class path, inside static method
prop.load(context.getClassLoader().getResourceAsStream("config.properties"));
This will work for both static and non static context and the best part is this properties file can be in any package/folder included in the application's classpath.

Your file should be available as com/example/foo/myProps.properties in classpath. Then load it as:
props.load(this.getClass().getResourceAsStream("myProps.properties"));

if your config.properties is not in src/main/resource directory and it is in root directory of the project then you need to do somethinglike below :-
Properties prop = new Properties();
File configFile = new File(myProp.properties);
InputStream stream = new FileInputStream(configFile);
prop.load(stream);

I see that the question is an old one. If anyone stumbles upon this in the future, I think this is one simple way of doing it.
Keep the properties file in your project folder.
FileReader reader = new FileReader("Config.properties");
Properties prop = new Properties();
prop.load(reader);

If your properties file path and your java class path are same then you should this.
For example:
src/myPackage/MyClass.java
src/myPackage/MyFile.properties
Properties prop = new Properties();
InputStream stream = MyClass.class.getResourceAsStream("MyFile.properties");
prop.load(stream);

Make sure that the file name is correct and that the file is actually in the class path. getResourceAsStream() will return null if this is not the case which causes the last line to throw the exception.
If myProp.properties is in the root directory of your project, use /myProp.properties instead.

You can use java.io.InputStream to read the file as shown below:
InputStream inputStream = getClass().getClassLoader().getResourceAsStream(myProps.properties);

Given the context loader.getResourceAsStream("myPackage/myProp.properties") should be used.
Leading '/' doesn't work with ClassLoader.getResourceAsStream(String) method.
Alternatively you could use Class.getResourceAsStream(String) method, which uses '/' to determine if the path is absolute or relative to the class location.
Examples:
myClass.class.getResourceAsStream("myProp.properties")
myClass.class.getResourceAsStream("/myPackage/myProp.properties")

Many answers here describe dangerous methods where they instantiate a file input stream but do not get a reference to the input stream in order to close the stream later. This results in dangling input streams and memory leaks. The correct way of loading the properties should be similar to following:
Properties prop = new Properties();
try(InputStream fis = new FileInputStream("myProp.properties")) {
prop.load(fis);
}
catch(Exception e) {
System.out.println("Unable to find the specified properties file");
e.printStackTrace();
return;
}
Note the instantiating of the file input stream in try-with-resources block. Since a FileInputStream is autocloseable, it will be automatically closed after the try-with-resources block is exited. If you want to use a simple try block, you must explicitly close it using fis.close(); in the finally block.

None of the current answers show the InputStream being closed (this will leak a file descriptor), and/or don't deal with .getResourceAsStream() returning null when the resource is not found (this will lead to a NullPointerException with the confusing message, "inStream parameter is null"). You need something like the following:
String propertiesFilename = "server.properties";
Properties prop = new Properties();
try (var inputStream = getClass().getClassLoader().getResourceAsStream(propertiesFilename)) {
if (inputStream == null) {
throw new FileNotFoundException(propertiesFilename);
}
prop.load(inputStream);
} catch (IOException e) {
throw new RuntimeException(
"Could not read " + propertiesFilename + " resource file: " + e);
}

A good practice which is not state in previous solution is to passing properties especially the property files that generated in compile time with build plugins perhaps, is to Use PropertySourcesPlaceholderConfigurer
#Bean
public static PropertySourcesPlaceholderConfigurer placeholderConfigurer() {
PropertySourcesPlaceholderConfigurer propsConfig
= new PropertySourcesPlaceholderConfigurer();
propsConfig.setLocation(new ClassPathResource("myProp.properties"));
propsConfig.setIgnoreResourceNotFound(true);
propsConfig.setIgnoreUnresolvablePlaceholders(true);
return propsConfig;
}
then can accessing the properties from IOC as demand such
#Value("${your.desired.property.pointer}")
private String value;

For Reading Properties file with its original order:
File file = new File("../config/edc.properties");
PropertiesConfiguration config = new PropertiesConfiguration();
PropertiesConfigurationLayout layout = new PropertiesConfigurationLayout(config);
layout.load(new InputStreamReader(new FileInputStream(file)));
for(Object propKey : layout.getKeys()){
PropertiesConfiguration propval = layout.getConfiguration();
String value = propval.getProperty((String) propKey).toString();
out.print("Current Key:" + propkey + "Current Value:" + propval + "<br>");
}

Specify the path starting from src as below:
src/main/resources/myprop.proper

Related

Cannot be resolved to absolute file path because it does not reside in the file system

My Code:
XWPFDocument doc = new XWPFDocument(OPCPackage.open(ResourceUtils.getFile("classpath:assets/OPTIONS_" + jubilar1.getJubiLanguage().toUpperCase() + ".docx")));
I have already tried instead of .getFile(), extractJarFileFromURL or resource.getInputStream() but all this does not work. When I package my project and run it as a jar file and it tries to open the following file it always returns the following message.
Error:
java.io.FileNotFoundException: class path resource [assets/OPTIONS_DE.
docx] cannot be resolved to absolute file path because it does not
reside in the file system:
jar:file:/home/tkf6y/IdeaProjects/hrapps/backend/target/backend-3.0.0.jar!/BOOT-INF/classes!/assets/OPTIONS_EN.docx
So yes it was the problem, as you are now using an InputStream as I suggested. The problem was (and always has been) the getFile stuff. What I suggest to do is don't use what you have now but rather do a new ClassPathResource(your location).getInputStream()) instead, it is easier, or even use a ResourceLoader (a Spring interface you can inject) and then use the path you had an again use getInputStream(). –
This works for me.
String strJson = null;
ClassPathResource classPathResource = new ClassPathResource("json/data.json");
try {
byte[] binaryData = FileCopyUtils.copyToByteArray(classPathResource.getInputStream());
strJson = new String(binaryData, StandardCharsets.UTF_8);
} catch (IOException e) {
e.printStackTrace();
}

Parsing a .properties file with getClassLoader()

I'm writing a Java program that takes a foo.properties file and parses it into a Properties object. After a quick search, I found this code:
public Properties getProperties() throws IOException{
String fileIn = "foo.properties";
Properties p = new Properties();
InputStream inStream = getClass().getClassLoader().getResourceAsStream(fileIn);
if(inStream != null) {
p.load(inStream);
} else throw new FileNotFoundException();
return p;
}
My question concerns line 4: why does the code above use InputStream inStream = getClass().getClassLoader().getResourceAsStream(fileIn), instead of simply using, say, FileinputStream fInStream = new FileInputStream(fileIn)?
The getResourceAsStream() can load files from the classpath rather than an absolute location. Refer to this excellent article
You can load .properties file even if your program is inside JAR repo

How to use values of build.properties in another property file using selenium webdriver

I am using eclipse for selenium webdriver. I have assigned an URL to the variable 'webdriver.url' in build.properties file. I have created another property file called 'ExpectedResults.properties'. I want to use the value of variable webdriver.url of build.properties in ExpectedResults.properties file. Is it possible to use. If possible can you please tell how it will be?
Thanks in advance.
Not clear whats the objective is. Two cases are possible here -
1.Assuming you have url in 'webdriver.url' variable.
You can write it to second property file ('ExpectedResults.properties') as
Properties prop = new Properties();
OutputStream output = null;
try {
output = new FileOutputStream("ExpectedResults.properties");
prop.setProperty("expected.url", webdriver.url);
prop.store(output, null);
} catch (IOException io) {
io.printStackTrace();
}
2 You can read both property files & compare URLs -
Properties prop = new Properties();
InputStream input = null;
try {
input = new FileInputStream("filename.properties");
prop.load(input);
System.out.println(prop.getProperty("webdriver.url"));
}
catch (IOException ex) {
ex.printStackTrace();
}

Properties setting via Servlet

I want to set data from configures.properties via servlet. configures.properties is locating in WEB-INF/classes. This is how I'm getting data:
public static String getDbPassword() {
Properties prop = new Properties();
try {
// load a properties file
InputStream in = Configures.class.getResourceAsStream(INPUT_FILE);
prop.load(in);
// get the property value
return prop.getProperty("dbPassword");
} catch (IOException ex) {
ex.printStackTrace();
}
return null;
}
But how to set? This is how I did:
public static void setDbPassword(String str) {
Properties prop = new Properties();
try {
//load a properties file
InputStream in = Configures.class.getResourceAsStream(INPUT_FILE);
prop.load(in);
prop.setProperty("dbPassword", str);
prop.store(new FileOutputStream(INPUT_FILE), null);
} catch (IOException ex) {
ex.printStackTrace();
}
}
But I'm catching java.io.FileNotFoundException after this. I think it happens after prop.store(new FileOutputStream(INPUT_FILE), null);. How should I modify OutputStream?
UPD:
This is how INPUT_FILE looks:
private static final String INPUT_FILE = "/config.properties";
Your INPUT_FILE is a resource path which getResourceAsStream will resolve relative to the classpath, but you're then trying to pass the same string to the FileOutputStream constructor which will try and treat it as an absolute path relative to the root of the filesystem. These are two different locations.
You could use ServletContext.getRealPath("WEB-INF/classes" + INPUT_FILE) to get the path you need for the FileOutputStream.
But the higher level issue here is that you shouldn't assume that your web application will have write access to its WEB-INF, or even that the directory exists on disk at all (e.g. if the app is running directly from a WAR rather than a directory unpacked on disk). If you want to store configuration data that can change then it should go in a file at a known location outside the web app (the location of this file could be an init parameter) where you know you will have read and write permission. This also stops your changes being overwritten when you deploy a new version of the app.
URL url = Configures.class.getResource(INPUT_FILE);
File file = new File(url.toURI());
OutputStream outputStream = new FileOutputStream(file);
...
prop.store(outputStream, null);
Try a FileWriter instead:
Writer writer = new FileWriter(INPUT_FILE);
...
prop.store(writer, null);
Can you try the following:
While reading the file
URL url = classLoader.getResource(INPUT_FILE);
InputStream in = url.openStream();
While writing :
new FileOutputStream(url.toURI().getPath())
Any files in your webapp should be considered read only. If you want mutable data you should use a database or some other data store.
J2EE advises against manipulating local files as it raises issues of clustering, transactions and security among other things.

i want relative path for a file in java

I am new to java. I want to read a properties file in java. But i have my properties file in a different path in the same project.
I don't want to hard-code it. I want try with dynamic path.
Here is my code,
Properties properties = new Properties();
try{
File file = new File("myFile.properties");
FileInputStream fileInput = new FileInputStream(file);
properties.load(fileInput);
}catch(Exception ex)
{
System.err.println(ex.getMessage());
}
my file is in the folder, webapp/txt/myFile.properties.
Can any one help me in solving this issue?.
One way to solve this is split the absolute path to you file in two parts
Path till your project folder
path from you project folder onwards (Relative path)
You can tread these two properties in your application and concatenate and get the absolute path of the file. The relative path remains configurable.
public Properties loadDBProperties() {
InputStream dbPropInputStream = null;
dbPropInputStream = DbConnection.class
.getResourceAsStream("MyFile.properties");
dbProperties = new Properties();
try {
dbProperties.load(dbPropInputStream);
} catch (IOException ex) {
ex.printStackTrace();
}
return dbProperties;
}
you can call this method from
dbProperties = loadDBProperties();
String dbName = dbProperties.getProperty("db.schema");//you can read your line form here of properties file
if its under webapp/txt.myFile.properties and webapp is the public web space, then you need to read it using absolute URL
getServletContext().getRealpath("/txt/myFile.properties")
Properties prop=new Properties();
InputStream input = getServletContext().getResourceAsStream("/txt/myFile.properties");
prop.load(input);
System.out.println(prop.getProperty(<PROPERTY>));

Categories