12

Where should I store persistent files in a Tomcat web app ?

  • javax.servlet.context.tempdir is not feasible, it's erased when the app is redeployed/removed
  • Don't want to use an absolute path in e.g. servlet init parameters
  • Storing the files in a database is not an option
nos
  • 223,662
  • 58
  • 417
  • 506
  • 2
    I take it you don't want to use a database? – Suppressingfire Nov 24 '09 at 20:15
  • 2
    Youll have to explain why a database is not an option, they are so basic and common that disallowing it surely means something else is going on. Maybe youre in a specially constrained environment we should know about. – Karl Nov 24 '09 at 20:46
  • 2
    It's not an option because it's not. I could go on about explaining how these large files need to be processed by legacy external tools that know nothing about databases, and showing them into a database just for the sake of pulling them right out again serves at the moment no purpose. There's more to it as well, but just take my word for it :-) – – nos Nov 24 '09 at 23:06

5 Answers5

10

Our team does this a lot. A general rule we follow is outside the web app and outside Tomcat.

Our sysadmin set up a directory on our server that the tomcat user has rw permissions to (e.g. /var/tomcat/persist). We have a built a directory structure under this that tomcat uses to store files, read app-specific init files, etc.

If you don't want to use an absolute path in your init-params for your servlet, consider setting a system property when tomcat is started up. The good thing about that is every application running under tomcat will have access to it. The bad thing about that is every application running under tomcat will have access to it. You could set a property named base.persist.dir and build subdirectories for each application underneath it. We set system properties in the setenv.sh script in the bin/ directory under the CATALINA_OPTS environment variable.

Andy Gherna
  • 2,135
  • 18
  • 22
5

Answering the title of the question, what about using a database, a DataSource and JDNI? Even in a web only context, writing to files using java.io is not really recommended because of concurrency, threading, security, clustering, portability issues. Some of these problems can be "workarounded" but still, this is not really a best practice. The standard approach is to use a database and I'd suggest to reconsider this option, throwing "file-based" lightweight database like HSQLBD or JavaDB into the mix.

(EDIT: For an unknown reason, database is not an option. Using JNDI or context parameters or init parameters to pass an absolute path - which are the less worse options IMHO - is excluded too. For a relative path, maybe look at user.home or user.dir then - or any other system property that you could pass on the command line. I don't like it, I wouldn't do it, and this doesn't solve the issues previously mentioned, but it's your choice after all.)

Pascal Thivent
  • 562,542
  • 136
  • 1,062
  • 1,124
4

Storing the files in a webapp directory under the home directory of the user running Tomcat is a good and convenient option. It is outside of Tomcat, which means it will survive redeployment, and it is usually a writable directory (because it is created under the users' home dir). But it is always a good idea to allow overriding the location of such directory via system property.

yossis
  • 1,243
  • 2
  • 11
  • 11
1

Generally, this would go to the database. But since the OP insists on not using a database, I'd try a different approach:

  • Filesystem path which is known: ${user.home}/.myapp. Applications sometimes use this for e.g. search indices which can be recalculated based on data in the database. Might be okay for your use case to use the user's home.
  • Store the configurable filesystem path in a configuration repository such as the database or perhaps Java Preferences (if you don't like to use servlet init params). Commercial applications such as Atlassian JIRA use a configurable (but absolute) filesystem path where they store issue attachments. If they don't know a better way, i don't know who does :)
mhaller
  • 14,122
  • 1
  • 42
  • 61
  • Writing to ${user.home} on tomcat7 (at least on Ubuntu) will result in a IOException because of permissions. – Jonathan Dec 22 '16 at 19:21
0

I generally would suggest to use a database to store persistent data and expose it via a DataSource.

If you don't want to do that, I guess you could consider using the "user.home" system property (I have seen this used in a few circumstances). But... there are no guarantees that your servlet will be run with permission to write access unless you configure that yourself.

Suppressingfire
  • 3,246
  • 23
  • 17