views:

133

answers:

4

Hi all,

I got a java web project handling several objects (again containing n objects of type A (e.g. time and value) and m objects of type B (e.g. time and String array)). The web projects itself contains several servlets/jsps for visualization as well as some logic for data manipulation and currently runs on an Apache Tomcat.

Is it possible to store the whole data in the servers (or most of the time: local) memory while the server is running? If the Tomcat is shut down, the data could be stored in a simple file, no restrictions there. On server startup, I just want to read in the files and write the objects to memory. How can I initiate the Tomcat to do so?

The reason why I do not want to use an extra database is, that I want to deliver a zip file containing the tomcat including the deployed *.war file (as I don't want my prof getting stuck with tomcat server setup etc.)

Thanks, ChrisH

+3  A: 

I think that HSQLDB is exactly what you need, a small database server that is also embedded natively in Apache Tomcat. It stores data in memory allowing also to write and read contents from a file.

Jack
Of course I'm assuming that you are talking about database objects, if you are talking about plain Java objects without any mapping to a database you should consider serialization.
Jack
If not necessary, I dont want to "mess" around with database objects and only use plain java objects.
ChrisH
So serialization is the best way, you just write objects on a file and then get back. However this kind of solution is ok for a small problem (like yours) but serialization is not as trivial as using a memory DB and must be handled with care!
Jack
Ok, thank you :) But I maybe will have to think about the embedded databases (as BalusC said), too, if I get too much data.
ChrisH
Actually having an embedded database is easier and more secure: you just do queries and everything is handled by database. In addition if you map Java objects with tables (there are many frameworks that allows you to do that) you really don't have to care about anything.I would suggest you the DB approach but since it needs more technical background I can understand that it can be scary :)
Jack
+1  A: 

If the app shuts down unexpectedly, you'll lose all your data, because it won't have time to write it to disk.

You could use a database like SQLite/derby/hsql etc. which store their data to the filesystem.

If you don't want to mess with a DB, then you could store everything in memory and flush it to disk every time it's modified. A couple tips here:

  • Serialization can make this really easy. Make all your objects implement Serializable, and give them a serial version id
  • use a BufferedOutputStream when writing to disk, this is faster than a straight FileOutputStream
  • DO NOT overwrite your old data file directly! Write to a new file, and when done writing, move the completed file on top of your old file. That way, if the server shuts down while you're in the middle of writing your data file, you still have the good file which was written before.
  • You should acquire a read lock on your data while writing it. Any other code which modifies the data should get a Write lock on the data.
Sam Barnum
I'd recommend copying the old file to a backup location, *then* renaming the newly written file for additional safety. (You could keep several backups that way.) But I'd go for the database solution myself ...
Jim Ferrans
+3  A: 

You could implement ServletContextListener and write the load-from-file and save-to-file logic in the contextInitialized() and contextDestroyed() methods which are invoked during webapp's startup and shutdown respectively.

You can read and write objects to disk, but they all need to implement java.io.Serializable first. Here is a Serialization tutorial with code examples.

That said, have you considered an embedded database so that you don't need to install a database server? You could use the JDK6's built-in JavaDB for this or its competitor HSQLDB. Alternatively, if it are pure key-value pairs, then you could also just use the java.util.Properties API for this (tutorial here). Just place the propertiesfile somewhere in the classpath and use ClassLoader#getResourceAsStream() to get an InputStream of it, or place it somewhere in WEB-INF and use ServletContext#getResourceAsStream().

BalusC
This sounds good. Is it possible to run the load-from-file logic right on server startup (or something similar) instead of on the first servlet call?
ChrisH
Sure, you can thus use the `ServletContextListener` for this. You only need to implement the interface accordingly and register it as a `<listener>` in the webapp's web.xml.
BalusC
Additionally, if you put the data in the application scope through `event.getServletContext().setAttribute("data", data)` then you can access it in servlets by `getServletContext().getAttribute("data")` and in JSPs by `${data}`.
BalusC
Ah, perfect. I think I now can figure everything to work properly. Particulary for JSPs it's a nice way to access the data! Thanks.
ChrisH
A: 

If you don't care about the possibility that your application may scribble all over your data files, your Tomcat / JVM may crash, or your machine may die losing all in-memory objects, then managing persistence as you suggest is an option. But you'll have quite a bit of infrastructure to build, test and maintain. And you'll miss out on the "value add" tools that most RDBMs provide; backup, a query tool, optimizers, replication, etc.

But if catastrophic data loss is not an option for you, you should use an RDBMs, ODBMs, whatever to do your persistence.

Stephen C