Stephen.Davies@anonymised.com wrote:
All,
GeoNetwork 2.2.0 is deployed into Tomcat 5.5.26. When attempting to shutdown the application hangs. Tomcat does not cleanly exit. This is causing problems in unix as the process must be manually killed (ports are being held open).
The problem appears to be with the way org.wfp.vam.intermap.kernel.TempFiles uses the Timer API. Changing line 55 from:
timer = new Timer();
to:
timer = new Timer(true);
forces the Timer to use a daemon thread. This allows Tomcat to shutdown completely.
1. At startup, Jetty prepares for its future shutdown
by using Runtime.addShutdownHook.
When the time for shutdown comes, it calls System.exit(0),
and the previously-registered shutdown hook does the
work of stopping the applications. A stray timer (or
other thread) can not stop shutdown.
2. Tomcat does not use System.exit(0) to shut down.
This is a deliberate design decision.
Applications are expected to clean up all threads.
A side-effect of doing GN development using
Jetty is that the "problem" of cleaning up threads
is swept under the carpet. Checking the
behaviour under Tomcat keeps us honest . . . .
In this case, the problem is that the Intermap
class starts up two Timer threads,
but only shuts down one of them.
1. The start() method does:
GlobalTempFiles.init(path, tempDir, delete);
tempFiles = GlobalTempFiles.getInstance();
and the stop() method does:
tempFiles.end();
So far, so good.
2. The start() method also does:
MapMerger.setCache(new HttpGetFileCache(path, cacheDir,
deleteCache));
The constructor of HttpGetFileCache starts
a Timer. But nowhere is there a call to stop
it.
Steve's change to the TempFiles class certainly
fixes the problem.
Here's another way to do it that matches the
cleanup of tempFiles.
1. Add the following method to HttpGetFileCache.java:
public void end() {
tf.end();
}
2. In Intermap.java:
(a) Add the following field to the class:
private static HttpGetFileCache httpGetFileCache;
(b) In the start() method, change:
MapMerger.setCache(new HttpGetFileCache(path, cacheDir,
deleteCache));
to:
httpGetFileCache = new HttpGetFileCache(path, cacheDir,
deleteCache);
MapMerger.setCache(httpGetFileCache);
(c) Add the following line to the stop() method:
httpGetFileCache.end();
I've done a quick test of this with Tomcat 5.5.26
and it seems to do the trick.
--
Richard Walker
Software Improvements Pty Ltd
Phone: +61 2 6273 2055
Fax: +61 2 6273 2082