A typical java application uses some values which are not suitable to be given in code such as log generation path, output location, configuration file path, timeout values etc. Since these values vary from system to system and user to user, their values can not be pre-fixed. One user may want his logs to be generated in “myLogs” folder, another user may want the logs to be generated in “appLogs” folder. If given in code, they cannot be changed without developer intervention. Further, this change would require a re-build of code.
Therefore, it is recommended to externalize these values and provide them in the form of properties or key-value pairs where the key is the string used in the code and is fixed while its value can be varied and set by the user. This value shall be used by our application to perform its normal operation, thus, making it configurable and user-friendly.
All the properties or the configuration to be externalized are collected in a properties file and is loaded at application startup. The properties file is generally a file with a .properties extension. It is not mandatory but a good practice so that property files may be recognized easily.
There are various ways to load a properties file in java. We shall discuss them one by one. The properties file used in the sample examples is named as test.properties and contains the following two properties:
type= website
Method 1 : Load Using a physical file path
static void loadPropertiesFromFileSystem() throws IOException {
String filePath = "C:\\test.properties";
InputStream input = null;
// initialize properties object which will hold properties
Properties prop = new Properties();
try {
// create an input stream pointing to the properties file
input = new FileInputStream(new File(filePath));
// load properties from input stream into properties object
prop.load(input);
// will print coDippa at the console
System.out.println(prop.getProperty("name"));
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (input != null) {
input.close();
}
}
}
Details : The above code simply creates a java.io.InputStream
to a file denoted by its absolute file path and passes this stream to a java.util.Properties
object which reads the file and loads it into the properties object. Property value may then be retrieved from Properties object using its getProperty(propertyName)
method.
File path may also be relative. For example, if the file is in a folder named “conf” inside your project, then file path may be given as “conf/test.properties”.
Method 2 : Load From a File On Classpath
static void loadClassPathProperties() throws IOException {
String filePath = "test.properties";
InputStream in = null;
Properties prop = new Properties();
try {
// create an input stream pointing to the properties file
// PropertyLoader is the name of class which contains this method
in = PropertyLoader.class.getResourceAsStream(filePath);
// load properties from input stream into properties object
prop.load(in);
System.out.println(prop.getProperty("name"));
} catch (IOException e) {
e.printStackTrace();
} finally {
if (in != null)
in.close();
}
}
Details : Another way to load properties is using getResourceAsStream()
method of java.lang.Class
class. This method searches for the resource according to the following order:
- If the path begins with a ‘/’, then the absolute path to the resource is used. For example, if the properties file resides in the package com.codippa.properties and the class in which we are loading the properties file is in the package com.codippa.loader then in order to load this file we need to provide file path as
getResourceAsStream("/com/codipaa/properties/test.properties")
. - If the path does not begin with a ‘/’, then it is considered as a path relative to the package of the java file in which you are loading the property file. For example, if your java class is in the package com.codippa.loader and the properties file is in the package com.codippa.loader.props, then the path will be given as
getResourceAsStream("props/test.properties")
which is relative to the package of java file.
Method 3 : Load From a File Using ClassLoader
static void loadPropertiesFromPackage() throws IOException {
String filePath = "test.properties";
InputStream in = null;
Properties prop = new Properties();
try {
// create an input stream pointing to the properties file
// PropertyLoader is the name of class which contains this method
in = PropertyLoader.class.getClassLoader().getResourceAsStream(filePath);
// load properties from input stream into properties object
prop.load(in);
System.out.println(prop.getProperty("name"));
} catch (IOException e) {
e.printStackTrace();
} finally {
if (in != null)
in.close();
}
}
Details : A third way to load properties is using getResourceAsStream()
method of java.lang.ClassLoader
class. This method takes the path of the file (or resource) to be loaded. This method considers all paths as absolute. That is, if you provide only the name of file, it will search the file inside project folders such as conf
, src
. If the file is in a package such as com.codippa
then the path of the file given to this method should be getResourceAsStream("com/codippa/test.properties")
. Please note that the path given to this method should NOT begin with ‘/’ as the path is considered as implicitly absolute.
Quick Reference of Both the Methods