18

My Java web application (myapp.war) ist deployed by placing it into the webapps direcotry on Tomcat on Ubuntu 10.04.

This application needs to save some data in files. But the user, which is running Tomcat (tomcat6) has no write access to the home directory /usr/share/tomcat6/ and no write access to the current working direcotry /var/lib/tomcat6/, since both belong to root.

So where should a web application store its data? I hope it is not the extracted archive in the webapps direcotry. This one could be deleted very easily by accident. And Tomcat can be configured, not to extract .war files. Then there would be no extracted direcotry.

Perhaps /var/lib/tomcat6/ should belong to user tomcat6 ant this is a bug in Ubuntu?

Pascal Thivent
  • 562,542
  • 136
  • 1,062
  • 1,124
Witek
  • 6,160
  • 7
  • 43
  • 63
  • There is no guarantee that a web container will allow you to use the file system... – Thorbjørn Ravn Andersen Jul 01 '10 at 21:37
  • Are you trying to read data or write it ? Normally web apps do not use the file system for saving data, they use a DB, a web service or a JMS queue to communicate to another system synchronously or asynchronously respectively. – Romain Hippeau Jul 02 '10 at 12:40
  • I need to read and write data. I have my own storage framework, which works much better then any database for me. – Witek Jul 02 '10 at 16:56

5 Answers5

4

If the files need not persist longer than the life-cycle of the servlet context, the servlet container provides a private temporary directory for each servlet context, specified by javax.servlet.context.tempdir attribute.

See Servlet Specification 2.3, Chapter 3 Servlet Context

3.7.1 Temporary Working Directories

The convenience of a temporary storage directory is required for each servlet context. Servlet containers must provide a private temporary directory per servlet context and make it available via the javax.servlet.context.tempdircontext attribute. The object associated with the attribute must be of type java.io.File

David J. Liszewski
  • 10,959
  • 6
  • 44
  • 57
3

Answering his own question, Witek stated /var/lib/tomcat6/webapps/ is writable -- at least on his installation of his version of Ubuntu. On my RHEL 5.2 system /var/lib/tomcat<X> doesn't even exist, so there is no webapps subdirectory writable or not, which leads to my answer.

Q: Where should a Java web application store its data?
A: Wherever you've configured it to store its data.

Make the location configurable, in web.xml as a <context-param> or in a myApplication.properties file.

  • I can put it where I want on my box, the SysAdmins can put it where they want on the production system.
  • You can change your mind later.
  • You don't need symbolic links (which have magically disappeared on me before, breaking the system.)
  • You can have several sets of test data, and just point the configuration at whichever one you want.
  • You can put it wherever there's disk space.
  • You are going to change your mind later.
Stephen P
  • 14,422
  • 2
  • 43
  • 67
  • 2
    Configuration in web.xml would cause big problems while updating. Every new .war delivered by developers would overwrite the admins configuration. – Witek Jul 02 '10 at 00:18
  • 1
    Reading a custom myApplication.properties file raises the problem, wehre to look for the file. – Witek Apr 23 '12 at 12:27
  • On Tomcat override web.xml context-param, env-entry, and resource-ref definitions with Parameter, Environment, and Resource elements in the Context element of YourWebAppName.xml file in the $CATALINA_BASE/conf/[enginename]/[hostname]/ directory (usually $CATALINA_BASE/conf/Catalina/localhost/). See the Apache Tomcat docs for the Context Container. – jla Nov 08 '19 at 00:47
2

I think it depends on what kind of data you are dealing with. Most of the time, data goes into the database simply because it is fast and easy to perform a CRUD. If you want to store localized user configuration and you don't care how portable it is, perhaps you can store under user.home, I did that for one of my projects and that works fine. All that being said, I really don't think there's any best practice on this and database seems to be the most obvious choice because you can do whole lot of different tasks against it, and most of them are free to begin with. :)

limc
  • 39,366
  • 20
  • 100
  • 145
2

I found the solution on Launchpad. /var/lib/tomcat6/webapps/ is writable. This means, that the following works:

File myFile = new File("webapps/myfile.txt");
Witek
  • 6,160
  • 7
  • 43
  • 63
  • 1
    Ok, but that's probably not a portable solution (it works with Tomcat, but might not work if you run your webapp on another Java EE app server). – Jesper Jul 01 '10 at 18:49
  • And it will not work if you change the working directory (the folder from where the command to start Tomcat is been issued). Using relative paths in Java IO is a terrible idea. Rather use absolute paths in Java IO like `/var/lib/tomcat6/webapps/myfile.txt`. – BalusC Jul 01 '10 at 19:02
  • Absolute paths would bind me to Tomcat on Linux. I would like to offer a .war file which just needs to be dropped to the webapps directory on nearly all possible platforms. – Witek Jul 02 '10 at 00:24
  • 1
    Then don't write to the filesystem, this is a NON PORTABLE solution (what if people can't write to the filesystem? What about clusters? etc, etc). – Pascal Thivent Jul 03 '10 at 18:39
  • Don't write to the filesystem? Writing to the filesystem is the purpose of my application. Not being portable. My web application IS THE DATABASE. – Witek Jul 03 '10 at 19:27
  • 1
    In a servlet, use new File( getServletContext().getRealPath("/myfile.txt") ) to get absolute paths from your application context relative paths. Inside JSP scriptlets you can use application.getRealPath() – Photodeus Jul 05 '10 at 00:18
0

I haven't seen any specific guidance on where you should store that kind of data locally - probably because you'd normally store that kind of data in a database.

When I need to store quick-and-dirty data like that, I store it on a filesystem specifically for that data, to isolate it from other areas where it might get caught up in other activity. Haven't had any issues with the approach so far. Also, if it's important, make sure you store it somewhere where you're backing it up :)

brabster
  • 42,504
  • 27
  • 146
  • 186