More action with Struts 2
In a recent review of Struts 2 in Action, JW Blogger Oleg Mikheev notes that Struts 2 is "just a collection of extensions built upon WebWork, which is ultimately the right thing to learn before starting a Struts 2 project." While Struts 2 has some architectural flaws, Oleg calls WebWork well-designed, well-tested, and reliable. What are your experiences using Struts 2 and WebWork?

Also see "Hello World the WebWork way," a JavaWorld excerpt from WebWork in Action, by Patrick Lightbody and Jason Carreira.

Newsletter sign-up

Sign up for our technology specific newsletters.

Enterprise Java
View all newsletters

Email Address:

Cleaning up after Jini services

Standardize the way Jini clients release finite nonmemory resources

In May 1998, I published "Object finalization and cleanup" in my Design Techniques column of JavaWorld. In this article, I gave advice on designing the end of object lifetimes. In particular, I tried to answer the question, "What the heck are finalizers for?"

The contract of finalize()

A finalizer is a Java instance method named finalize() that returns void and takes no arguments. Class Object declares such a method with the protected permission. The Java specifications make the following promise about finalizers:

Before reclaiming the memory occupied by an object that has a finalizer, the garbage collector will invoke that object's finalizer.


The javadoc page for class Object says the following about the finalize() method's purpose:

The general contract of finalize is that it is invoked if and when the Java virtual machine has determined that there is no longer any means by which this object can be accessed by any thread that has not yet died, except as a result of an action taken by the finalization of some other object or class that is ready to be finalized. The finalize method may take any action, including making this object available again to other threads; the usual purpose of finalize, however, is to perform cleanup actions before the object is irrevocably discarded. For example, the finalize method for an object that represents an input/output connection might perform explicit I/O transactions to break the connection before the object is permanently discarded.


The basic guideline

Although I suggested several guidelines for using finalizers in my Design Techniques article, my primary guideline was:

Don't design your Java programs such that correctness depends upon "timely" finalization.


I first heard this warning against writing Java programs that depend on "timely" finalization from Tim Lindolm, who was responsible for thread and garbage-collection mechanisms of Sun's original Java virtual machine (JVM). Tim gave this warning at the JVM Birds-of-a-Feather session at the first JavaOne conference in 1996. The problem with depending on timely finalization for program correctness is that you generally don't know how garbage collection will be performed inside a JVM. Therefore, since you don't know when (or even if) any particular object will be garbage collected, you don't know when or if it will be finalized.

The upshot of garbage collection in JVMs is that you must avoid writing Java programs that will break if certain objects aren't finalized by specific times during the program's execution. If you write such a program, it may work on some JVM implementations but fail on others.

Timely finalization and nonmemory resources

A more exact way to express the same basic guideline against timely finalization is to couch it in terms of finite nonmemory resources, such as sockets or file handles.

Don't depend on finalizers to release finite nonmemory resources.


This guideline considers that the primary way in which a program could depend on timely finalization is if the finalizer is used to release or retire some finite nonmemory resource, such as a file handle, a socket, memory allocated in a native method, or a running thread. Here's the example I gave in my Design Techniques article:

Resources