Java load properties file correctly - java

I have the following project structure:
ProjectName/src/java/com/main/Main.java
And I have a properties file in the following folder:
ProjectName/config/settings.properties
Now I tried to load the properties file in the Main.java with:
InputStream input = Main.class.getResourceAsStream("/config/settings.properties");
Properties prop = System.getProperties();
prop.load(input);
But this does not work. How is it the right way to do it?
Edit: I got the following error:
Exception in thread "main" java.lang.NullPointerException
at java.util.Properties$LineReader.readLine(Unknown Source)
at java.util.Properties.load0(Unknown Source)
at java.util.Properties.load(Unknown Source)
Edit2: Now it works with eclipse. I did the following (adapted from getResourceAsStream() is returning null. Properties file is not loading)
1) This directory [config] must be put into the "build path". Right-click the directory in the Package Explorer or Project Explorer view, select "Build Path", then "Use as Source Folder". Note: This build path will be the class path for the project, when you run it.
2) As the config directory now is part of your class path and contains your properties file, you can simply load it with InputStream input = Server.class.getClassLoader().getResourceAsStream("settings.properties");
This works well for eclipse but not yet for a jar. I think I also have to add the build path somehow to the ant script.
How can I do that?
Edit3: If I take the settings.properties out of the config folder in the jar, then it works. Why? I want it in the config folder in the jar too.

Use following :
InputStream input = Main.class.getResourceAsStream("../../../../config/settings.properties");
Properties prop = System.getProperties();
prop.load(input);
By adding ../ I am getting 1 step backward in your filesystem. In your code you were using /config....., which means C:/config..... (if it is in C drive).
The following will also work in your case. (but not in zipped file)
InputStream input = new FileInputStream("config/settings.properties");
Properties prop = System.getProperties();
prop.load(input);

getResourceAsStream find files relatively compiled (class) files on in jar file. Example:
Your compiled files are in bin directory than you should put properties file to bin/config/settings.properties for give access to it.

You are using maven. So follow the maven structure and keep your resources like prop, xml etc files in resource folder and then call.
So folder structure would be like this
src/main/resource|
|
config|
|
settings.properties
InputStream input = Main.class.getClass().getResourceAsStream("/config/settings.properties");

Three things
You need add the settings.properties to a jar (can be the same jar as your Main)
Your classpath should include this jar
You need to use the context Class Loader to load the properties file in you Main.
Classloader cl = Thread.currentThread().getContextClassLoader();
cl.getResourceAsStream("settings.properties");

Related

resources folder is not getting found in eclipse with InputStream in = getClass().getResourceAsStream("resources/template.properties");

I have an awt application which will be run using executable JAR file. Few Issues I am facing in getting resources folder
1. In Eclipse, If I use following code
properties = new Properties();
InputStream in =getClass().getResourceAsStream("resources/template.properties");
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
Then I am getting
ERROR 2019-11-11 12:03:44,052 [AWT-EventQueue-0]
java.lang.NullPointerException
If I use the above code in eclipse and when I export runnable Jar then it is working in JAR file but when I run in eclipse it is throwing nullpointer exception.
Case 2: But if I use below code and export JAR file then JAR file is throwing error as "in current directory resources is not available" even resources folder is present.
properties = new Properties();
InputStream in =
inputStream = new FileInputStream("resources/template.properties");
Folder structure
enter image description here
You shouldn't reference the resource folder in the file path string. But then, your resource folder needs to be a source folder for Eclipse.
I don't know your project strcuture yet, but I suggest you to create a resource folder on your project root, then rigth click on it and go to Build Path > Use As a Source Folder.
After that, all files inside that folder will both be directly accessed by the getResourceAsStream method, and also be placed on the JAR root, merged with all other files from the other source folders.
Then you can do:
InputStream inputStream = getClass().getClassLoader().getResourceAsStream("template.properties");
This way should work both inside Eclipse and in the standalone JAR.
PS: I strongly suggest you to start using Maven projects and follow its folder structure.
You don't need to specify the resources path if you do like this snippet bellow it might work.
InputStream inputStream = getClass()
.getClassLoader().getResourceAsStream("template.properties");

ClassLoader.getResource returning null while using File.getAbsolutePath

I have a config.ini file I need to open that is quite far back in directory so I used File.getAbsolutePath() to set the base directory and concatenated the remainder of the path.
Printing the path, I get the correct path that I can paste into file explorer, but the object returned is null.
So I started by initializing my Properties and ClassLoader as such:
Properties prop = new Properties();
ClassLoader classLoader = Test.class.getClassLoader();
Then I create the path. I tried escaping a back slash(1) as well as forward slash(2), both return null but both paths work in file explorer.
String absPath = new File("").getAbsolutePath();
absPath = absPath.concat("\\resources\\config\\config.ini"); // (1)
absPath = absPath.concat("/resources/config/config.ini"); // (2)
then I try to set the URL to open an InputStream
URL res = Objects.requireNonNull(classLoader.getResource(absPath), "Unable to open config.ini");
InputStream is = new FileInputStream(res.getFile());
However, the following returns null.
classLoader.getResource(absPath)
I expected this to properly open the file because the path was correct. I am using Intelij and I read that I needed to add the .ini resource file under settings > compiler, which I did but that did not resolve my issue.
Thank you!
That's not the way to load resources via class-loaders.
If your classpath is something like the following ...
java -cp resources;lib/my.jar ... org.mypack.MyClass
then you load it with this path
getClassLoader().getResource("/config/config.ini");
Your classpath includes the resources folder, and the class-loader loads from there.
The absolute path of the OS is quite certainly not in classpath.
In any case, you must be certain that the resource folder is in classpath.
If your config file is not in classpath then you can't use classloaders to load that file.
Just one more thing, if your configuration is not in classpath, but in a child directory of your working dir, why can't you simply use new FileInputStream("resources/config/config.ini");

How to maintain a configuration file in java application project like a configuration file in C# application?

In C#,when I want to create a configuration file, it's so easy,just right click the mouse and add a new configuration file, this file will be added into the solution and it's so easy to maintain.
But in java, I don't know what method is standard. I see some people use the properites file.If this is the most popular method, can some one tell me where to place this file? I saw some guy put it in the src folder, others put it in an external folder.
Can you tell me which is the standard? And what is the best practice to maintain a configuration.
I don't know if this is the "standard" way but I think it's the easiest. If you place your properties file in your project's root folder
- project
- config.properties
- src
- main
- ...
- test
When you create a File instance in Java and specify a relative filename, then the name is resolved against the directory that Java was launched from
e.g. if you launch java in your command prompt as follows:
cd C:\Users\Tom\example-project
java example-project
and this is your code:
File file = new File("tom.txt");
then the file variable will be resolved to the abolsute path: C:\Users\Tom\example-project\tom.txt
When you Run a project through Eclipse, Eclipse launches java from the root directory of the project, meaning that if you put your config file in the project's root folder then
File file = new File("name-of-config-file.properties");
will resolve to the correct config file on your system.
This has an added benefit if you create a runnable JAR, as you can just place your config file in the same directory as your JAR and the code will continue to work (the config file location will be resolved relative to the JAR).
If you put your config file in /src folder then you need to have separate code for when running from Eclipse and when running as a JAR
With regards to sample code:
//Read properties from disk
File propertiesFile = new File("config.properties");
FileReader reader = new FileReader(propertiesFile);
Properties props = new Properties();
props.load(reader);
//Set and get properties
props.setProperty("NewProperty", "value");
String propValue = props.getProperty("propToGet");
//Write properties to disk
FileWriter writer = new FileWriter(propertiesFile);
props.store(writer, "Added x properties");
Configuration files are used to store,read write user settings.
I think for web apps you can use web.xml.And for other you should use Properties class to read and write settings.
As for where to place it,If you dont specify path it is stored in your root folder other than that you have to provide explicit path.

Load a properties file in a jar file

I was trying to work on a java program with requires a properties file attached to the jar. Thus, i did jar the program, and unjar it to attach a properties file. I have a class, MyClass, which requires the properties file. Thus, i basically put the properties file to the same folder as MyClass.class. Then I jarred it back.
In my MyClass.java, i was trying to access the properties by:
Properties prop = new Properties();
prop.load(MyClass.class.getClassLoader().getResourceAsStream("prop.properties"));
Where prop.properties is in the same folder as my MyClass.class.
It failed to load it. Any help will be appreciated !
Thanks,
ClassLoader.getResourceAsStream() treats the path as relative to the root of the classpath, i.e. it looks for resources at the root level of each JAR or directory on the class loader.
You probably want Class.getResourceAsStream, which treats the path as being relative to the package of the class in question. You also need to make sure to close the stream once you've read it.
Properties prop = new Properties();
InputStream in = MyClass.class.getResourceAsStream("prop.properties");
try {
prop.load(in);
} finally {
in.close();
}
If MyClass is in the package com.example then this will load com/example/prop.properties from the JAR.

Including a property file with the Jar file in a single folder

I am creating a java application in Eclipse Helios.I have created a class in which i need to have data from the .properties file which i added in the folder containing the solution .Through this code i can accesss the value from the .properties file when i try to run it in Eclipse.
The code is:
Properties prop = new Properties();
prop.load(new FileInputStream("config.properties"));
_url = prop.getProperty("url");
Through this code i am getting the correct value of the Url .
After this i have created an executable jar of my project .When i tried to execute the jar using command line then i got a FileNotFoundException ,means the jar is not able to locate the .properties file.
I have kept the .properties file in the same folder as of Jar file as we have the provision of editing the .properties file.
Since i started working in Java for only 4 days ,i am unable to figure out about where to place the .properties file and how to access it.
Please help.
For jar try to use:
prop.load(getClass().getClassLoader().getResourceAsStream("config.properties"));
if you call from static context use:
prop.load(YourClassName.class.getClassLoader().getResourceAsStream("config.properties"));
You need to ask the class loader to get a resource.
See http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/ClassLoader.html
Properties prop = new Properties();
prop.load(classLoader.getResourceAsStream("config.properties"));
_url = prop.getProperty("url");

Categories

Resources