Utility: eclipse stop button shutdown hook workaround

An outstanding issue with IDE environments (Eclipse/NetBeans/etc) is the fact that under IDE environment pressing the "red stop" button to terminate the application while running or debugging causes the process to terminate so abruptly as not to allow java VM hooks to execute and perform the necessary cleanup, among other things. Just look at this Eclipse bug 38016.

On the flip side, when running under normal console display and pressing CNTRL-C will send a nice signal (in Unix speak 'kill -1'). The process terminates gently, VM hooks execute as expected and everything is rosy.

Outside of jumping into Eclipse source and ripping things apart the only work arounds I have seen is to send a "kill -1" signal externally to the process running under Eclipse. Not an easy solution.

I've come up with my own work around I would like to share. The idea is this, if you are running your application in an environment that does allow a GUI to be displayed (probably won't work under web container, etc), display a tiny "button" with an action attached to it to shutdown the application nicely. The default behavior is to call on "System.exit(0)" which is called from the SWING event thread.

What is this button?

The button is an undecorated SWING frame that contains a single component, the JButton. The default size of the button is 15x15 pixels and is colored RED. The button is moved by dragging it with the RIGHT mouse button right over the Eclipse's stop button and the button will always stay on top covering the actual button underneath.

If you click the button with the LEFT mouse button it will execute the action, which by default is to call "System.exit(0)". And, yes... the button does remember its current position next time you re-run your application and will be placed at the last place you shut the application down.

Again, this is a work around and I wouldn't recommend using this in any production code. However if you are looking for a clean shutdown of your java application under any IDE control, this will do it, as long as the application is not under some kind of container that can not launch a SWING application.

Here is some code:

import com.slytechs.debug.swing.StopButtonFrame;
// .. skipped class setup code
new StopButtonFrame();

Just create the button anywhere at the beginning of your application or jUnit testcase. If this is the first ever this button is displayed, it will be at some other part of the screen. Just drag it and position it over the IDE stop button with the RIGHT mouse button. Then press the button with LEFT mouse button when you want to shut down your app/testcase cleanly.

Here is a second example that registers a different action on button press:

new StopButtonFrame() { 
	public void processStopButtonAction() {
		System.out.println("Stop Button Pressed!!!!");
		System.exit(0);
	};
};

Example with few bells and whistles:

StopButtonFrame stop = new StopButtonFrame(20, 20) { 
	public void processStopButtonAction() {
		System.out.println("Stop Button Pressed!!!!");
		System.exit(0);
	};
};

stop.setTooltipTextf("Feeds: %d%nSegments: %d%nLength: %dMB%nTotal: %dMB%n",
		BUFFER_COUNT,
		SEGMENT_COUNT,
		SEGMENT_LENGTH / (1024 * 1024),
		TOTAL);

If we have this GUI up anyways, why not add some useful information to the tooltip when we hover the mouse of the button. The normal SWING setTooltipText method is there as well, but this convenience method allows you to use printf() style syntax to format multi-line output. Should be self-explanatory.

And finally, yes there is a StopButtonAction interface to register your own custom action. The action is set on the button frame using setStopButtonAction(StopButtonAction action) method.

To set a different size, just pass width and heigh in pixels to the constructor.


Download version r1: 7Kb

License: use is unrestricted!

Credit: The stop button uses a class ComponentMover by Rob Camick (http://tips4java.wordpress.com/2009/06/14/moving-windows) - thanks for the excellent and comprehensive mover!