using finalize() to persist objects

W

Will

Hi,

I have a webapp which uses an in-memory queue to hold requests for
processing.

I'm trying to come up with a way to persist the contents of the queue
to disk when the webapp is gracefully shutdown.

I know that the JVM can call the finalize() method on an object just
before garbage collection, however, when I put some serialization code
into the finalize() method of the queue, it never seems to get called.

To me, using finalize() in this fashion seems quite clunky anyway.

Would anybody be able to suggest a better way of doing this? I just
need to ensure that the queue is persisted to disk when the app is
shutdown.

Many thanks in advance,

Will
 
R

Ryan Stewart

Will said:
Hi,

I have a webapp which uses an in-memory queue to hold requests for
processing.

I'm trying to come up with a way to persist the contents of the queue
to disk when the webapp is gracefully shutdown.

I know that the JVM can call the finalize() method on an object just
before garbage collection, however, when I put some serialization code
into the finalize() method of the queue, it never seems to get called.

To me, using finalize() in this fashion seems quite clunky anyway.

Would anybody be able to suggest a better way of doing this? I just
need to ensure that the queue is persisted to disk when the app is
shutdown.
There is no guarantee that any object's finalizer will ever be called since
there's no guarantee that any object will ever be garbage collected. A finalizer
is never the appropriate place for business logic of any kind, even if it's just
persistence. You're looking for a ServletContextListener, most likely:
http://java.sun.com/products/servlet/2.3/javadoc/javax/servlet/ServletContextListener.html
 
R

Roland

Hi,

I have a webapp which uses an in-memory queue to hold requests for
processing.

I'm trying to come up with a way to persist the contents of the queue
to disk when the webapp is gracefully shutdown.

I know that the JVM can call the finalize() method on an object just
before garbage collection, however, when I put some serialization code
into the finalize() method of the queue, it never seems to get called.

To me, using finalize() in this fashion seems quite clunky anyway.

Would anybody be able to suggest a better way of doing this? I just
need to ensure that the queue is persisted to disk when the app is
shutdown.

Many thanks in advance,

Will
You could add a shutdown hook:
<http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Runtime.html#addShutdownHook(java.lang.Thread)>,
but read it's Javadoc carefully: a shutdown hook will only run when the
program exits normally, or when the virtual machine is terminated in
response to a user interrupt (CTRL-C).
--
Regards,

Roland de Ruiter
___ ___
/__/ w_/ /__/
/ \ /_/ / \
 
R

Roland

You could add a shutdown hook:
<http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Runtime.html#addShutdownHook(java.lang.Thread)>,
but read it's Javadoc carefully: a shutdown hook will only run when the
program exits normally, or when the virtual machine is terminated in
response to a user interrupt (CTRL-C).
OK, i didn't read carefully enough :-[ .
You were talking about a web app. A shutdown hook is not gonna help you
there.
--
Regards,

Roland de Ruiter
___ ___
/__/ w_/ /__/
/ \ /_/ / \
 
M

Malte

Will said:
Hi,

I have a webapp which uses an in-memory queue to hold requests for
processing.

I'm trying to come up with a way to persist the contents of the queue
to disk when the webapp is gracefully shutdown.

I know that the JVM can call the finalize() method on an object just
before garbage collection, however, when I put some serialization code
into the finalize() method of the queue, it never seems to get called.

To me, using finalize() in this fashion seems quite clunky anyway.

Would anybody be able to suggest a better way of doing this? I just
need to ensure that the queue is persisted to disk when the app is
shutdown.

Many thanks in advance,

Will
Just guessing here, but does not a Servlet/JSP have a destroy() method
you could use?
 
R

Ryan Stewart

Malte said:
Just guessing here, but does not a Servlet/JSP have a destroy() method you
could use?

Yes, but that method may be called at any time, not just when the app is shut
down.
 
G

GregSmith

The Java Servler Whitepaper
(http://java.sun.com/products/servlet/whitepaper.html) Says...

"<i>Requests are processed until the servlet is explicitly shut down by
the web server, by calling the destroy method. The servlet's class may
then become eligible for garbage collection. </i>"

So, you should be able to serialize in the destroy() method.

Greg
 
J

John C. Bollinger

Will said:
Hi,

I have a webapp which uses an in-memory queue to hold requests for
processing.

I'm trying to come up with a way to persist the contents of the queue
to disk when the webapp is gracefully shutdown.

I know that the JVM can call the finalize() method on an object just
before garbage collection, however, when I put some serialization code
into the finalize() method of the queue, it never seems to get called.

No object's finalize() method is ever guaranteed to be called, because
no object is guaranteed to ever be garbage collected. In particular,
objects are unlikely to be garbage collected at application shutdown
(where in your case, the relevant "application" is the servlet container).
To me, using finalize() in this fashion seems quite clunky anyway.

It is. Plus, overriding Object.finalize() (even trivially) on any class
makes the GC work much harder to collect instances of that class.
Would anybody be able to suggest a better way of doing this? I just
need to ensure that the queue is persisted to disk when the app is
shutdown.

Create an appropriate ServletContextListener implementation and register
it in your web.xml. Yours is squarely among the kinds of problems that
ServletContextListeners are intended to solve.
 
D

Darryl L. Pierce

If you read the specifications, you'll see that there's no guarantee
that finalize() will ever be called.
 
J

John C. Bollinger

GregSmith said:
The Java Servler Whitepaper
(http://java.sun.com/products/servlet/whitepaper.html) Says...

"<i>Requests are processed until the servlet is explicitly shut down by
the web server, by calling the destroy method. The servlet's class may
then become eligible for garbage collection. </i>"

So, you should be able to serialize in the destroy() method.

No, he can't. The servlet container is free at any time to destroy() a
servlet instance and replace it with a new instance of the same servlet
class. It could even delay creating the new instance until a request is
received that maps to that servlet. In the case of a servlet that
implements SingleThreadModel, the container is even free to maintain
multiple instances concurrently, in which case it would be completely
incorrect to serialize in the servlet's destroy() method.

The servlet API defines a means for a web application to receive
notification when it is being shut down (the ServletContextListener; see
my other response). If shutdown notification is what is desired then
that API should be used, not some hack that may (or may not) be found to
work under the initial development conditions.
 
R

Ryan Stewart

John C. Bollinger said:
No object's finalize() method is ever guaranteed to be called, because no
object is guaranteed to ever be garbage collected. In particular, objects are
unlikely to be garbage collected at application shutdown (where in your case,
the relevant "application" is the servlet container). [...]
Create an appropriate ServletContextListener implementation and register it in
your web.xml. Yours is squarely among the kinds of problems that
ServletContextListeners are intended to solve.
Holy crap. I wish usenet messages propogated faster. When I started reading this
message, I thought I was reading the message I posted to this thread 2.5 hours
earlier, they're so similar. I assume you hadn't seen mine when you posted this.
 
A

Adam Maass

Darryl L. Pierce said:
If you read the specifications, you'll see that there's no guarantee
that finalize() will ever be called.
Well, you have to read them pretty darn closely to glean this bit of
information. It is correct, though.

-- Adam Maass
 
R

Ryan Stewart

Adam Maass said:
Well, you have to read them pretty darn closely to glean this bit of
information. It is correct, though.
Actually it's perfectly reasonable and logical. If you're coming from a C++
background, I can see how you would mistakenly take a finalizer to be similar to
a destructor, but otherwise the way it works makes perfect sense.
 
T

Thomas Bühler

Will said:
Hi,

I have a webapp which uses an in-memory queue to hold requests for
processing.

I'm trying to come up with a way to persist the contents of the queue
to disk when the webapp is gracefully shutdown.

I know that the JVM can call the finalize() method on an object just
before garbage collection, however, when I put some serialization code
into the finalize() method of the queue, it never seems to get called.

To me, using finalize() in this fashion seems quite clunky anyway.

Would anybody be able to suggest a better way of doing this? I just
need to ensure that the queue is persisted to disk when the app is
shutdown.

Many thanks in advance,

Will

Hello,

You can try to add a 'shutdownHook':

Runtime.getRuntime().addShutdownHook(new Thread("Startup
Shutdown") {

/**
* Do operations on Exit.
*/
public void run() {
System.out.println("Storing data:");
}

});

Best regards
Thomas Buehler
(e-mail address removed)
 
W

Will

Hi,

Thanks to everyone for their suggestions.

Finalize() is definitely a bad idea as I suspected.

It sounds as though a ServletContextListener is going to be the best
way forward for me here.

Thanks again!

Will
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,997
Messages
2,570,240
Members
46,830
Latest member
HeleneMull

Latest Threads

Top