57

I create a web application (WAR) and deploy it on Tomcat. In the webapp there is a page with a form where an administrator can enter some configuration data. I don't want to store this data in an DBMS, but just in an XML file on the file system. Where to put it?

I would like to put the file somewhere in the directory tree where the application itself is deployed. Should my configuration file be in the WEB-INF directory? Or put it somewhere else?

And what is the Java code to use in a servlet to find the absolute path of the directory? Or can it be accessed with a relative path?

informatik01
  • 16,038
  • 10
  • 74
  • 104
boes
  • 2,835
  • 2
  • 23
  • 28

6 Answers6

49

What we do is to put it in a separate directory on the server (you could use something like /config, /opt/config, /root/config, /home/username/config, or anything you want). When our servlets start up, they read the XML file, get a few things out of it (most importantly DB connection information), and that's it.

I asked about why we did this once.

It would be nice to store everything in the DB, but obviously you can't store DB connection information in the DB.

You could hardcode things in the code, but that's ugly for many reasons. If the info ever has to change you have to rebuild the code and redeploy. If someone gets a copy of your code or your WAR file they would then get that information.

Putting things in the WAR file seems nice, but if you want to change things much it could be a bad idea. The problem is that if you have to change the information, then next time you redeploy it will overwrite the file so anything you didn't remember to change in the version getting built into the WAR gets forgotten.

The file in a special place on the file system thing works quite well for us. It doesn't have any big downsides. You know where it is, it's stored seperatly, makes deploying to multiple machines easy if they all need different config values (since it's not part of the WAR).

The only other solution I can think of that would work well would be keeping everything in the DB except the DB login info. That would come from Java system properties that are retrieved through the JVM. This the Preferences API thing mentioned by Hans Doggen above. I don't think it was around when our application was first developed, if it was it wasn't used.

As for the path for accessing the configuration file, it's just a file on the filesystem. You don't need to worry about the web path. So when your servlet starts up it just opens the file at "/config/myapp/config.xml" (or whatever) and it will find the right thing. Just hardcodeing the path in for this one seems pretty harmless to me.

MBCook
  • 14,424
  • 7
  • 37
  • 41
  • This works for us too, but it can be a pain if you occasionally deploy on Windows, where it isn't natural to add /opt and the like. – Peter Hilton Sep 18 '08 at 20:38
  • 9
    Rather than referencing the full path to the file you can put the "config" directory on the classpath for the server and just use ClassLoader.getResource(). – John Meagher Sep 19 '08 at 00:12
  • 6
    We specify a system property when tomcat starts up. Our app gets our config directory from this system property, so we can use a different configuration directory from server to server. – ScArcher2 Sep 19 '08 at 15:57
  • @Peter: My dev setup was on Windows. I just created the directory on my box off C so that when the application asked for "/config", it would get the right directory. It worked quite well. – MBCook May 26 '11 at 20:51
  • @John: That's actually a pretty good idea, this was simply the setup when I got there. – MBCook May 26 '11 at 20:52
  • 2
    In the application I am currently working on we are storing config file outside of the application in a folder located in USER_HOME directory. And on startup, application gets the file from the location String absoluteConfigPath = System.getProperty("user.home") + File.separator + ".myapp" + File.separator + "config.xml"; – Nikola Jan 11 '13 at 00:42
  • 2
    just a small remark: according to the filesystem hierarchy guide http://www.tldp.org/LDP/Linux-Filesystem-Hierarchy/html/opt.html, all files should go under /opt/'package'/config where 'package' is the name of your program. – milan Jan 15 '14 at 15:20
  • @MBCook Thank you for your comment. It has cleared my doubts. – Vimal Panchal Oct 17 '16 at 14:14
  • 1
    How would this work if you have multiple environments (e.g. test and staging) running in the same tomcat? Since you cannot specify a system property per environment when you only have one tomcat. – AtliB Jun 11 '17 at 14:07
16

WEB-INF is a good place to put your config file. Here's some code to get the absolute path of the directory from a servlet.

public void init(ServletConfig servletConfig) throws ServletException{
    super.init(servletConfig);
    String path = servletConfig.getServletContext().getRealPath("/WEB-INF")
Jataro
  • 2,548
  • 1
  • 17
  • 17
  • 10
    This is not a compatible approach - it's not guaranteed by the servlet spec that getRealPath() will return a valid (non-null) path or even that the war is unpacked at all (IMHO, Weblogic will not extract files from the .war to disk). – MRalwasser Apr 23 '12 at 09:35
  • 5
    This won't work if you have a dev, test, pre-prod and prod environment, as you would need an individual .war for each environment. You should be able to deploy the configuration once, and then propagate the same war through the environments... – Tom Chamberlain Oct 07 '15 at 09:26
9

Putting it in WEB-INF will hide the XML file from users who try to access it directly through a URL, so yes, I'd say put it in WEB-INF.

Michael
  • 34,873
  • 17
  • 75
  • 109
6

I would not store it in the application folder, because that would override the configuration with a new deployment of the application.

I suggest you have a look at the Preferences API, or write something in the users folder (the user that is running Tomcat).

Hans Doggen
  • 1,796
  • 2
  • 16
  • 13
3

The answer to this depends on how you intend to read and write that config file.

For example, the Spring framework gives you the ability to use XML configuration files (or Java property files); these can be stored in your classpath (e.g., in the WEB-INF directory), anywhere else on the filesystem, or even in memory. If you were to use Spring for this, then the easiest place to store the config file is in your WEB-INF directory, and then use Spring's ClassPathXmlApplicationContext class to access your configuration file.

But again, it all depends on how you plan to access that file.

delfuego
  • 14,085
  • 4
  • 39
  • 39
1

If it is your custom config WEB-INF is a good place for it. But some libraries may require configs to reside in WEB-INF/classes.

axk
  • 5,316
  • 12
  • 58
  • 96