Simple Java Configuration Files and no XML in Sight

Filed Under Computers, Java on December 30, 2006 at 12:26 am

The last time I discussed Java configuration files it was from the point of locating them on the disk the right way. This time I want to comment on the content of configuration files. There seems to be an obsession with XML in the modern world. Some people seem to think that shoe-horning XML into their applications will somehow magically make them great. I don’t want to completely put down XML because it most certainly has its uses. In fact I use it quite a bit to store complex and potentially incomplete data sets. However, using XML to store simple configuration information is over-kill and makes the configuration file needlessly complex to edit and needlessly complicates your application. Unless you’re writing something huge or some thing complex the chances are you’re configuration file won’t need to be complicated. The chances are all you really need are some name-value pairs to specify a few parameters. If this is the case Java comes with a wonderfully simple solution right out of the box, .properties files.

Technorati Tags: , ,

The syntax for a .properties file could not be simpler; all lines beginning with a # are comments and all other lines are in the form:

  1. <key>=<value>

Below is a sample configuration for the Virtual Learning environment I’m working on:

  1. # Basic portal config
  2. BASE_URL=www.eve.nuim.ie/evePortal
  3.  
  4. # Database stuff
  5. DB_JNDI_NAME=jdbc/eve_portal
  6.  
  7. # File locations
  8. DATA_DIR=/var/eve-data
  9. PDFLATEX_BIN=/opt/local/bin/pdflatex
  10. IMAGEMAGICK_BIN_DIR=/opt/local/bin

If you choose to use this type of configuration file you can locate and open it all in one step by using functionality built into the java class loader as follows:

  1. Properties configFile = new Properties();
  2. configFile.load(this.getClass().getClassLoader().getResourceAsStream("/my_config.properties"));

You can they read out any key in the following way:

  1. some_var = configFile.getProperty("some_key");

Simple as that, no need to load complex parsing libraries, no big long messy code. Unless you have a good reason to go with a more complex format you really should be using .properties files.

Comments

53 Responses to “Simple Java Configuration Files and no XML in Sight”

  1. Matt Skibbs on November 21st, 2007 3:21 am

    Thanks for the post! I’m new to Java and I was looking for something similar to a .NET app.config and this worked well for my needs.

    There is a minor typo in this line:

    resourceFile.load(this.getClass().getClassLoader().getResourceAsStream(“/my_config.properties”));

    It should be:

    configFile.load(this.getClass().getClassLoader().getResourceAsStream(“/my_config.properties”));

    Again, thanks for the post :)

  2. Bart B on November 21st, 2007 12:29 pm

    Hi Matt,

    Thanks for that. I’ve fixed the typo.

    Bart.

  3. Orlin on December 13th, 2007 8:04 am

    There is another typo:
    properties configFile = new Properties();
    It should be:
    Properties configFile = new Properties();

    I was unable to use the load Method until i changed Properties to java.util.Properties.
    There is another Properties Class located in com.sun.xml.internal.fastinfoset.sax, which is somehow preffered from my jdk…

  4. Bart B on December 13th, 2007 12:00 pm

    Hi Orlin,

    Thanks for pointing out typo, fixed now. Strange that the sax class got priority over the java.util one. I can only imagine that happening if you had imported both java.util.* and com.sun.xml.fastinfoset.sax.* in the one file. If you do all your imports explicity and avoid using wild characters that can of course not happen. That is of course a proverbial pain unless you have a nice IDE like Eclipse to look after most of the work for you.

    Bart.

  5. OMomani on April 23rd, 2008 9:21 am

    hey all, thanks alot for this post :)

    i’m new to java, i want to load the config file from inside my Main() “static void Main()” but i cant, i always get “non-static variable cannot be referenced from a static method”…
    how can i do that!!!!!??

  6. Bart B on April 23rd, 2008 10:32 am

    Hi OMomani,

    You should be able to load the config from within a static method like main but it has to be done a little differently because there is no ‘this’ within a static method. To get the class loader you need to get at the Class object for your class. If you’re in a non-static context you do that with this.getClass() but as you found out you can’t do that from within a static context (like main). You need to replace the this.getClass() bit with:

    ClassName.class

    Where you repalce ClassName with the name of your class.

    Hope that helps,

    Bart.

  7. OMomani on April 23rd, 2008 12:14 pm

    Thank you Bart for your reply!

    i have added a (propertiesfile) named it MyConfig
    and in my main i want to retrieve a variable that is in MyConfig… i got it that i cant use “this” in main but what ClassName should i provide instead of “this.getClass()”? honestly, i dont know what to put instead coz it’s the first time to java! should i put “Main.class”??

    can you help me plz!

    many many thanx.

    OMomani

  8. Bart B on April 24th, 2008 9:52 am

    Hi OMomani,

    You need to put in the name of the class containing the main method. It will be the same as the name of your file.

    Bart.

  9. Andrea Rota on May 18th, 2008 10:20 am

    You can use also:

    Properties configFile = new Properties();
    configFile.load(new FileInputStream(“configuration.conf”));
    my_value = configFile.getProperty(“my_key”);

  10. Adam on July 30th, 2008 9:40 am

    Hi,

    first of all eclipse requires me to handle IOexception and then it can’t locate my file anyway. I’m using configFile.load(this.getClass().getClassLoader().getResourceAsStream(“/home/user/configFile”));

    Am I doing something wrong?

  11. Bart B on July 30th, 2008 2:51 pm

    Hi Adam,

    Class loaders are for loading classes from your class path rather than from a regular file system path. The whole point of using class loaders is to avoid hard-coding in file system paths like the one you are trying to use above. If you want to use a hard-coded file then use a regular FileInputStream to access it rather than a ClassLoader.

    Hope that helps,

    Bart.

  12. Bala on August 6th, 2008 3:27 pm

    your previous answer is fine. but the issue is i am having my .properties file in the root folder. given such a situation how do u access the properties file. i am seriously confused as to where this .properties file should end up. i have it in the root folder in my development envrionment.

  13. Bart B on August 8th, 2008 3:22 pm

    Hi Bala, sorry for the slow reply!

    It needs to go into the base of your class path. By far the easiest way to do that is to put it in the folder where your classes end up after you build. Or, if your development environment is set up sensibly, put it where your source files are and the build process should copy it to your classes folder.

    Hope that’s some help.

    Bart.

  14. Antonio on September 5th, 2008 10:38 pm

    This is a great post.

    Just one thing. I was getting “Error null” in the class loader line. To fix the error I changed (“/my_config.properties”) to (“my_config.properties”) without the slash, if I put the file in the root. If I put it inside a package I use (“myPackage/my_config.properties”) without the first slash.

    Just wanted to comment it in case someone has the same problem.

    p.s. I’m new in java, too.

  15. james on December 3rd, 2008 11:19 pm

    Hi, I want to use this idea for coursework in for next week.. Im just wondering.. but say if a user of the program changes the configuration, How would I write to the configuration file?

  16. Bart B on December 4th, 2008 12:32 pm

    Hi James,

    I’m really not sure if this is the right way to store user-editable configuration details. This is more for low-level stuff to get the app to lauch in my view. I’d be inclined to store user editable configuration detail in a database of some sort, and store the details for connecting to that database in a config file like this. If your application was not going to be database driven you might consider a simple serverless database like SQLite, or perhaps a regular file, the location of which is stored in the config file.

    Hope that helps and good luck with your course work.

    Bart.

  17. Patrick M. on December 18th, 2008 5:33 am

    Great post, I must say!! I looked into the Properties class to see if there was maybe a way I can save a variable as an integer, rather than a String. Is this at all possible? I know the Properties class will only pull a String from a .properties file, but you wouldn’t happen to know a work-around, would you?

    I.E:
    In my file I would have: “my_int=1000″ and in my java file I would have “int my_int = configFile.getProperty(“my_int”);” but I get an “incompatible types” compiler error. Any work-around? I am clueless.

  18. Bart B on December 18th, 2008 2:05 pm

    Thanks Patrick! I don’t see any need to complicated things, just a simple type conversion should do the trick, something like:

    int my_int = Integer.parseInt(configFile.getProperty(”my_int”));

    Bart.

  19. Patrick M. on December 18th, 2008 2:42 pm

    Oh, that worked great! Thanks for the simple solution, not sure why I didn’t think of that…

  20. Peter Lawrey on December 21st, 2008 11:25 am

    I have added a page to Wikipedia on this topic.
    http://en.wikipedia.org/wiki/Java_Configuration
    It might be a good place to add additional comments.

  21. Steven on January 5th, 2009 11:03 am

    Thank you! Very usefull post.

  22. Hamza on April 9th, 2009 3:45 pm

    Hi, thanks for this post. I have a problem reading the config-file. I get a NullPointerException (unkown source)! I have saved it where the class-files are generated. is this wrong? where should the file be saved?

  23. Bernt on April 29th, 2009 6:13 am

    Hi, Thanks alot!

  24. Ali on April 30th, 2009 3:45 am

    i have the configuration.conf file in the same folder as my jar file. I am trying to access the properties file using

    Properties configFile = new Properties();
    configFile.load(new FileInputStream(”configuration.conf”));
    String foo = configFile.getProperty(”my_key”);

    but this is not working. How can I access the properties file from a jar file.

  25. Bart B on April 30th, 2009 1:07 pm

    Hi Ali,

    If your classes are in the JAR then the config file has to be in the JAR too. The file must be in your class path, the folder containing the JAR isn’t.

    Bart.

  26. se on May 1st, 2009 11:19 pm

    Hi Bart,

    it is more work answering questions than writing the blog entry, isn’t it? :) But in earnest, tnx for your explanation regarding the properties file. It helped.

    Keep it up!

    Regards,
    se

  27. Ryan on May 27th, 2009 2:19 pm

    Thanks for the useful tip. I’m new to Java and that’s really slick–just what I was looking for.

  28. Implementation Decisions for the Display Class - The Intellog Blog - It’s time for a little intelligent dialogue. on August 28th, 2009 3:52 pm

    [...] XML would be the correct format in which to store the display-specific information.  However, Bart Busschots makes a pretty good case for going with the Java .properties flow and using the very simple format [...]

  29. Seshu on December 13th, 2009 3:05 am

    Bart!!! Good Post. Its really helpful. Looking forward for your new posts…

  30. Dave on January 8th, 2010 7:25 pm

    In response to Ali:

    You can load a properties file that isn’t in the jar. Use Bart’s code to load:

    configFile.load(this.getClass().getClassLoader().getResourceAsStream(“myConfig.properties”));

    But when you export your project as a jar, add this to the manifest:

    Class-Path: myConfig.properties

    And ensure that myConfig.properties is in the same directory as your jar.

  31. Jerred Smithson on March 31st, 2010 12:53 pm

    How do you retain the “/” character when retrieving the DATA_DIR property?

  32. Justin on May 8th, 2010 11:17 pm

    Thanks Bart,

    it was my first time trying to get values from a .properties file and your post really helped.

    I managed to get the thing to work in a “normal” java class. But what I wanted was to give the user the ability to change the ipaddress in a .properties file in an Android project. Is this familiar to you (or anyone else out there)?

    I did manage to access the .properties file but I don’t get the desired “change file without the need to recompile effect” I wanted… (it’s like it reads it only once even thought the code to load the file is executed more than once, by launching the app again that is). I end up having to run the project again for the changes to take place…

  33. Bart B on May 9th, 2010 1:14 pm

    Hi Justin,

    To be honest it sounds like you’re trying to use the wrong tool for the job. .properties files are not for user-settings, but rather for sysadmins to tweak things on a per-instance basis. If you had the same web app in many places and wanted each instance to configured slightly different they are perfect. But as you found out, you do have to re-start the server each time you change them.

    For user-editable preferences I’d suggest a lightweight database of some kind. Perhaps a simple flat-file database like SQLite (http://www.sqlite.org/). Or, if you app uses a DB anyway, just create a preferences table.

    To put things into context, a .properties file would be a great place to store the details needed to connect to a DB in which you would then store the varying data.

    Hope that helps,

    Bart.

  34. Steve Bennett on June 3rd, 2010 4:52 am

    Ok, I’m a bit confused. I thought a .properties file would be useful for per-instance settings, but suddenly it seems to become very complicated, involving manifests, compiling the file into the .jar file, using classloaders etc etc. And creating a database simply to store two or three string properties? Complete overkill, surely.

    So…what *is* the best, super lightweight way to simply be able to read a couple of properties from a text file, either in the working directory, or in the directory where the .jar is found, so they can be easily modified by the user?

  35. Bart B on June 3rd, 2010 6:57 am

    Steve,

    To just read sttings .properties are the easiest way, but not to write. If your users can handle editing a text file to set the preferences then sure, .properties files are very much your friend. But for user-editable settings where your app would have to write to the file, they’re not. I’d either suggest creating some sort of configuration object and serialising it to a file (using Java’s in-built serialisation method), or using a very lightweight and simple flat-file database like SQLite. There is no database server with SQLite, it really is just a nice way or reading and writing data to a file in an organised way. There may be other ways, but those are the solutions that spring to mind. Personally, all the Java apps I write are database driven, so I just use a .properties file to store the connection details for the DB, and have all the other options in there. I have used the serialisation option to store recovery data to allow an app to easily pick up where it left off and it really is very easy. You just need to be sure all the classes you write implement the interface java.io.Serialisable.

    Hope that helps,

    Bart.

  36. Air Climber on October 5th, 2010 2:50 pm

    Thanks, very good post. And thanks Matt and Orlin for pointing out the typos. I was a little confused the first time I read it.

  37. ra on October 22nd, 2010 10:21 am

    Should the extension of a config file need to be a .prop or .config. please explain.. in spring batch .config is used for retreiving values.. values are grouped together is blocks like

    common
    {
    name=”raji”;
    }
    special
    {
    error count=”30″;
    }

  38. Bart B on October 22nd, 2010 11:13 am

    Hi Ra,

    Since you give the full file name, including the extension, to the function to load the file, it really doesn’t matter what you call it from a functional point of view. That means that it’s a matter of taste for the developer what to call them. What ever makes the most sense to you would seem to the right thing to do!

    Bart.

  39. Rajath on February 7th, 2011 9:11 am

    Hi guys,

    Thanks for the discussion and ideas. I could write a config file and use it successfully.

  40. Kris on February 9th, 2011 3:39 am

    I am kind of new to the config file world. I have to do a project where we store ip addresses in a config file so that we can ping them through a java program. Do you have any tips for doing this?

  41. Suhani on May 18th, 2011 9:23 am

    Hello Bart,

    The article is very useful.I am able to display the details which i have defined in conf property file on jsp page. Now i need to save the details which i have edited on jsp page back to my conf property file. How can i achieve this?

  42. Bart B on May 18th, 2011 3:18 pm

    Suhani – the simple answer is that you don’t do that kind of thing with a properties file, that’s what databases are for!

    Where properties files come into the picture is that they allow you to specify the details for connecting to the DB. They are read-only data stores.

    Bart.

  43. Suhani on May 19th, 2011 12:03 pm

    For response to Kris,

    Hi, Kris

    You can proceed like this in your config file define the field details you want to read as a key and then give its path,something like this,
    Appache_address = C:/Program Files/Apache Software Foundation/Apache2.2
    Now create a java class and a method inside it which will read this key vaue(Appache_address)and call the object of this new java class along with the method, where you want to use it.

  44. Nate on July 12th, 2011 7:11 pm

    I am not really seeing the advantage of using this technique.

    I’m sure the code behind the Properties class is just as messy, if not more messy, than the custom XML code.

    Also, I think most people are looking for a configuration file that can be edited by the user. I saw that a light database was recommended as an alternative to the Properties class. Well….an XML file is a light database…..

    Also, if the goal is to merely capture property settings that are not going to be edited by the user, then why no just use a simple file stream? What’s the point of using the Properties class?

  45. Bart B on July 12th, 2011 7:57 pm

    Hi Nate,

    The key difference is that the properties file are addressed via the CLASS PATH, not via a FILE PATH.

    For a GUI application this has the advantage of nothing having to hard-code the location on the file system that the app is installed to in order to be able to locate your config file. You wouldn’t use them to store the actual user preferences, just to enable your app to find the file on disk where you’ll store those kinds of things, perhaps as SQLite, perhaps as XML, or perhaps in some other format. How else do you avoid hard-coding in the location of the config file into your code?

    If you expand your view out even further to web applications written in Java for deployment on a Java-based web server like Apache’s Tomcat the advantages become even clearer. The vast vast bulk of web apps use databases as their main data store, but you need to specify how the app should access the DB before it can use it to access any of the data in the DB. It’s not at all unusual to have multiple instances of an web app installed on the same server, either as multiple instances for multiple customers, or perhaps a live instance and a dev instance for testing code changes. When you are in this situation you need each instance to have it’s own configuration file, but each instance is also running the identical code. How then do you achieve that?

    Simple, you need something that loads from the CLASS PATH, not a file system path. Each instance can load a file at the IDENTICAL location within the Class Path and get a different files containing different DB connection details. This is why the properties file mechanism exists, it give you a per-instance name space as opposed to a per-computer name space like the regular file system does.

    Now – you argue that you think the code to process a trivially simple format like properties files will be as messy as the code to parse a massively complex standard like XML, I’m sorry, but there’s no nice way to say this, you’re barking mad if you really believe that! I can write a parser for .properties files in literally a few lines of code, can you do the same for XML? I doubt it!

    Here’s the algorithm I’d use:
    Start by initialising a hashtable of some form to store the properties, this hash will be indexed by the property names in the .properties file, and store the matching values.
    Loop through the file one line at a time, and for each line do the following:
    1) check if the line is empty, if so, skip
    2) check if the line starts with a #, if so, skip
    3) split the line on the first = character encountered
    4) insert the entry into the hash table using everything before the first = as the key, and everything after as the value.
    When done looping, return the hashtable.

    That’s it!

    There is no earthly way to do XML parsing anywhere near that simply.

    Also – you have simplicity and readability in your code. If all you need is simple key-value data, then your code cannot get simpler than using .properties files. XML is always a messier undertaking, and involved importing libraries too.

    Properties files are not the answer to all problems, but they are a simple and efficient solution to some very significant real-world problems.

    XML has it’s uses too, but it’s also often horribly abused, it’s like the proverbial sledge hammer being used to hammer in nails a lot of the time.

    Bart.

  46. zilik on July 22nd, 2011 10:36 am

    Hello Bart,

    Thank you very much for your post, it helped me a lot!

    However, it would be awesome if I could “encrypt” the .prop file some way, so the user couldn’t edit it. How can I achieve this?

    Looking forward for your future Java related posts,
    zilik

  47. Bart B on July 23rd, 2011 10:18 pm

    Hi Zilik,

    I can’t think of an easy way to encrypt the whole file, but you definitely could use obfuscated keys and encrypted values. There are many crypto libs for Java, so you really can take your pick of how to encrypt the values.

    Now – you would have to hard-code the decryption key into the app, so if someone took the time to reverse compile your app they could get the key and hence be able to edit the values anyway.

    I guess if you REALLY want to go all out you could use asymmetric encryption, encrypting the vars with a private key that you never ever store on the system where the app will be running, and then hard-coding the public key into the app. This would mean that someone who reverse-compiled the app could read the settings in the file, but not change them.

    Hope that’s of some use to you,

    Bart.

  48. kheimon on September 11th, 2011 9:20 am

    thank you you saved me a bunch of time

  49. Phil on February 20th, 2012 12:53 pm

    Hi Bart, great post. Hope you will be as patient and polite with me as with others.
    I am new to java and want to use a .properties file for the classic reason you have expressed here i.e. Connecting to a db from different environments where the code might be running.
    I used your code ‘as is’
    Properties configFile = new Properties();
    configFile.load(this.getClass().getClassLoader().getResourceAsStream(“/db.properties”));

    but i get an error in my eclipse:
    Multiple markers at this line
    – Syntax error on token “load”,= expected after this token
    - Syntax error token(s), mispleced construct(s)
    And there are no default proposals offered by eclipse

  50. Dev on March 15th, 2012 6:56 am

    sir,

    am new to configuration file setups in a project.
    i know about property file and how to read it by using java. But i want to add menus in UI using property file. i dont know how is it possible.

    can u help me…

  51. Bart B on April 8th, 2012 1:49 pm

    Hi Philip,

    Sorry for the slow reply, I’m very bad at staying current with blog comments.

    I THINK that error is from the smart quotes WordPress has placed around the strings. Replacing them with regular quotes instead of ones sloping left and right should do it.

    Bart.

  52. Bradley on May 1st, 2012 7:07 am

    Hey,

    I was wondering how I set this up to read a file that is located like this:

    Folder1 (contains the jar that will read config)
    Folder2 (contains configfile.config)

    This did not seem to work but it was my best guess:
    (“../Folder2/configfile.config”)

  53. EJ on October 15th, 2012 10:37 am

    Thanks a lot!
    I was able to make a config file and load variable successfully thanks to your post and discussion.
    Have a nice week!
    EJ

Leave a Reply




Before you post a comment please remember that commenting on my blog is a privilege not a right. I won't approve comments that are obscene, offensive or insulting. For more info please read this post.

Subscribe without commenting