0

I would like to embed a Derby database in a servlet-based application running on Tomcat.

For this purpose, I need to persist the database files on the disk. I would prefer for them to reside in a sub-folder of the deployed web application (which I could then convert using getServletContext().getRealPath()).

Is there a good practice wrt acceptable, application-relative locations where a servlet could safely write to? If no such recommendation exists, what would be a tomcat-specific good practice?

This discussion seems to rule out writing in WebContent; will I have to write to a CATALINA_HOME sub-folder, as some tutorials point to (but it feels hackish)?

Community
  • 1
  • 1
oparisy
  • 2,056
  • 2
  • 16
  • 17
  • As to the `getRealPath()` matter, it's bad because any changes which you made there will get lost whenever you redeploy the WAR or even when you restart the server which auto-redeploys an existing WAR. The simple reason is that those changes are not contained in the original WAR at all. – BalusC Dec 10 '12 at 14:12

2 Answers2

1

When you are installing an application would you rather see your data stored somewhere in /usr/bin (or C:/Program Files) or rather in your home directory where the rest of your data lies?

Don't couple your application binaries (which never change) with the data it operates on. You don't want to loose the data when deleting an application and vice-versa. User home directory or even better - folder selected during installation - is much better.

Tomasz Nurkiewicz
  • 334,321
  • 69
  • 703
  • 674
  • How would you define "user home directory" in the context of a server-deployed app? I understand not writing into WebContent is indeed motivated by the risk of deletion due to a redeployment. – oparisy Dec 07 '12 at 23:08
1

You need to make the filesystem persistence location an explicit parameter to your program, probably as a property (i.e. -DdataStoreLocation=somepath). In general, a Java application may or may not have access to a filesystem -- it could be running from within a WAR or even have been loaded from the network and have no classpath-relative filesystem.

Making it an explicit requirement and part of your app's contract with the user is the only way to guarantee that there's a filesystem to use, and a way to get the path name to use.

Jim Garrison
  • 85,615
  • 20
  • 155
  • 190
  • OK, so your answer is "no": no universally available filesystem location a Servlet can write to exists. So I should stick to a datasource (which report, as you suggest, location / configuration choices at deployment time) or, to still be able to use an embedded database, pass its filesystem location as an argument (can I do this using `server.xml`? JNDI?). – oparisy Dec 08 '12 at 09:23
  • It is possible that there is no filesystem, but unlikely. The Context is just another way that a Java application can interact with its environment, if that environment is an app server. There is a system property `java.io.tmpdir` that is for temporary filesystem resources, but there are no guarantees that things placed there will persist indefinitely. Since you are specifically asking about servlets, the Context is as good a place as any to provide the path information. – Jim Garrison Dec 08 '12 at 19:19