Ways To Load a property file.

Hi All,

I have been trying to get ways to load .properties file into my application. The problem is am not able to get how i will be able to load it as a variable(Path to property file). My App is a war file so I can not keep it in classes folder as it will be changeable also.

So I thought of keeping the property file name and path as a variable so that I can load it from anywhere in the server system.

I want a class through which I can load my property file from multiple places like:
As system variable: E.g: -DMYPROP.FILE=D:\abc.properties
As Environment variable: E.g: set MYPROP.FILE=D:\abc.properties
From user.home directory and CLASSPATH and work.directory

my properties file contains 2 fields LoginName and Password all in encrypted format.

I have given my code snippet below.
Can somebody let me know how to do it exactly.
So that the class will check in all these environement variables location for the property file and will load the Key values which ever is first found.

Because I tried multiple types and all ended in Null pointer exception after giving the environment variables too.
private String validateUser(String userId, String password) throws IOException {

        String append = null;
//        String passprop = "1";
//        if (System.getProperty(Property.MYPROP_FILE).equals(null)) {
//        return passprop;
//        }
//        ResourceBundle bundle = ResourceBundle.getBundle(System.getProperty(Property.MYPROP_FILE));
//        String LoginName = bundle.getString("LoginName").trim();
//        String Password = bundle.getString("Password").trim();

        Properties props = new Properties();
          try {
             props.load(new FileInputStream(System.getProperty(Property.MYPROP_FILE)));
             //catch exception in case properties file does not exist
             catch(IOException e)
        String LoginName = props.getProperty("LoginName");
        String Password =props.getProperty("Password");

        try {
      //String LoginName = "admin";
       // String Password ="admin";
            if (LoginName.trim().equals(PassPS.getInstance().encrypt(userId).trim()) && Password.trim().equals(PassPS.getInstance().encrypt(password).trim())) {
                append = LoginName;
        } catch (Exception ex) {
            Logger.getLogger(Login.class.getName()).log(Level.ALL, null, ex);
    return append;

Open in new window

Ramakanta SahooAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.


is a bad way to check it... The proper check is
System.getProperty(Property.MYPROP_FILE) == null

null is the only value for which you are checking with == instead of equals when dealing with objects,

And make sure that Property.MYPROP_FILE contains the value you expect.

Back to your question:
Just start going through the different places and if you cannot read them in one way, continue with the next one.

Something like
String username = null;
String pass = null;
//read from one type. If something goes wrong or you cannot read them, set username=null;
if (username == null){
//the previous reading failed so start a second way if you cannot read them, set username=null;
and so on and so on.

Where exactly do you have troubles with this approach?
Ramakanta SahooAuthor Commented:
Sorry to for a confusing question.
What I meant to say is after even giving -DMYPROP.FILE=D:\abc.properties in JAVA_OPTS of server it throws a null pointer exception as if it is not getting the MYPROP_FILE property. If I give the hard coded full path to the abc.properties file instead of System.getProperty(Property.MYPROP_FILE) it works perfectly.

I just want it to load the abc.proerties file from where ever it will find the value as MYPROP.FILE as a environment variable or as of a system propery. Now its not doing it.

I just want to know what shall i do extra to let it take the property file which ever path I will mention during the start of the server JVM.

 props.load(new FileInputStream("D:\abc.properties"))); WORKS

 public static final String MYPROP_FILE= "MYPROP.FILE";
 props.load(new FileInputStream(System.getProperty(Property.MYPROP_FILE)));

Its not able to get the abc.properties file @ D:\abc.properties but if I hard code the path it works fine and I am able to login.

type Exception report


description The server encountered an internal error () that prevented it from fulfilling this request.



note The full stack trace of the root cause is available in the Apache Tomcat/6.0.20 logs.

Open in new window

See http://www.esus.com/javaindex/j2ee/servlets/servletreadenv.html
And also try System.getenv()  instead of System.getProperty (with some moditifications - see the documentation)
Bootstrap 4: Exploring New Features

Learn how to use and navigate the new features included in Bootstrap 4, the most popular HTML, CSS, and JavaScript framework for developing responsive, mobile-first websites.

Ramakanta SahooAuthor Commented:
As my app will be a WAR file i cant change my web.xml file for a custom path to property file and there is no way my clients will allow to change there servers web.xml file for putting custom property path. They can maximum allow me to add a -DMYPROP.FILE parameter to server start or as a environment variable so I cant do it on the referred url way..

I will check out for the System.getenv().

Why not adding in web.xml? As long as you use your own variable, I do not see why they would not allow it... That's the standard way anyway... And considering that web.xml is per application - it should not be a problem.

If you need it to be changed often, just pass a placeholder name in web.xml and then in the servlet read from the placeholder where the real file is (for example pass WEB-INF/classes/paths.props and then inside of paths.props specify where the real file is... in this way you won't need to change the web.xml all the time if that is such a big problem)...
Ramakanta SahooAuthor Commented:
As the deployment is a WAR file I cannot ask them to go to exploded war files WEB-INF/classes/paths.props file and change it to something else as it will be a big headache for server admins during updation and redeployments as exploded WAR folder will get removed and redeployed and the changes will go off. They will not accept to change the path each time some new patch comes.

And I dont know which place in server they will prefer to keep the properties file.
They have asked some way to push the path to properties file as a parameter to a variable which they can use a environment variable instead of a hard-coded path in some file because the properties file will contain few sensitive info.Though it will be in encoded format but still its a security issue in big orgs policies.

What they want is they should be able to change the path to the properties file when they ever want to like a startup parameter
like in JAVA_OPTS:
-Dprop.file=whateverpath/abc.props file.
I should be only querying the prop.file to get the property file for my app login.
So what happened with System.getenv()?
Mick BarryJava DeveloperCommented:
> JAVA_OPTS=%JAVA_OPTS%;-DMYPROP.FILE=D:\abc.properties;

should be a space instead of a ;


why can't you package the properties file with your app?
objects, good catch for the ; :)
What app/web server are you using? With Tomcat, you need to set a environment variable that contains the properties you want to pass to the JVM.

set CATALINA_OPTS="-DMYPROP.FILE=D:\abc.properties"
Ramakanta SahooAuthor Commented:
I did a ps -eaf | grep -i java and found that the the servers java thread had no java property called -DMYPROP.FILE in runtime thread. So I added JAVA_OPTS="-DMYPROP.FILE=/home/temp/abc.properties" to startup.sh and exported the variable and restarted and then only(After adding "export JAVA_OPTS") I was able to see the property name with other properties in the java thread of running server.

So learning is when you start server from command line put the JAVA_OPTS and export JAVA_OPTS in startup.sh/bat file and when its been started by NetBeans IDE it needs to be added and exported in catalina.sh/bat. As in netbeans 6.8 if you give the same -DMYPROP.FILE=blah in run time "VM Options" panel, it does not take it into the JVM's real running environment so seems some bug there. :)

I dont know if it is right place to ask or not but just asking if somebody can point me out to some place or some sample code .
I want to encrypt the properties file and keep it . So each time it wants to load it will decrypt the file and read the encrypted strings from the file. Is there anything which I can do to encrypt and decrypt the file for better security.


Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Ramakanta SahooAuthor Commented:
@objects @Venabili

Sory that ";" is my writting mistake while putting the question here.

I have yet to try getEnv() but for now its not on priority as its working.
Now encryption of file is P1 :)

Many thanks
The snippet below encrypt the data with a key that is stored in text file. AES is one of the most prefered symmetric encryption alogorithm available. The implementaftion uses standard Java JCE using a key that you can create using the createKey() method.

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;


   public void encrypt() {
                /* Initialize the byte array in which to store the encrypted data */
                byte[] encrypted = new byte[1];
                String encodedString = null;
                try {
                        /* Read the AES key String from the file */
                        // String str_key = readKeyFromFile();
                        // String str_key = skeySpec;
                        byte[] key = skeySpec.getEncoded();
                        BASE64Encoder base64Encoder = new BASE64Encoder();
                        encodedString = base64Encoder.encodeBuffer(key);
                        // System.out.println(encodedString.getBytes());
                        FileOutputStream fos = new FileOutputStream("d:\\file.txt");
                        DataOutputStream dos = new DataOutputStream(fos);
                        /* Use of BASE64Decoder to read the key stored in BASE64 format */
                        BASE64Decoder base64Decoder = new BASE64Decoder();
                        byte[] key_byteform = base64Decoder.decodeBuffer(encodedString);
                         * Regeneration of SecretKeySpec from the raw bytes retrieved after
                         * BASE64 decoding
                        SecretKeySpec skeySpec = new SecretKeySpec(key_byteform, "AES");
                        /* Instantiate the cipher */
                        cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
                        /* Initialize the cipher in ENCRYPT mode with key for encryption */
                        cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
/*call doEncrypt with text and cipher
doEncrypt("My text", cipher);
        private String doEncrypt(String strencryptText, Cipher cipher)
                        throws BadPaddingException, IllegalBlockSizeException, SQLException {
                String strreturnEncryptedText = "";
                byte[] encrypted = new byte[1];
                encrypted = cipher.doFinal(strencryptText.getBytes());
                BASE64Encoder base64_encoder = new BASE64Encoder();
                strreturnEncryptedText = base64_encoder.encodeBuffer(encrypted);
                return strreturnEncryptedText;
public SecretKeySpec createKey() {
                try {
                         * The class KeyGenerator provided the functionality of
                         * symmetric-key keygenerator
                        KeyGenerator kgen = KeyGenerator.getInstance("AES");
                         * Initialize the key generator with the keysize. The key size is an
                         * algorithm specific metric specified in number of bits
                        kgen.init(128); // 192 and 256 bits may not be available
                        /* Generate the SecretKey */
                        SecretKey skey = kgen.generateKey();
                        String keyFormat = skey.getFormat();
                        /* Get the key in the encoded format */
                        byte[] raw = skey.getEncoded();
                        /* Construct an algorithm specific secret key from byte array */
                        skeySpec = new SecretKeySpec(raw, "AES");
                } catch (NoSuchAlgorithmException nsae) {
                return skeySpec;

Open in new window


Wrong question maybe? :)
In continuation of the same question; but yes may be he should ask a new question for encryption :)
Ah - haven't seen that the Asker asked :) but it should have been a different question, yes.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Editors IDEs

From novice to tech pro — start learning today.