Reputation: 1179
In my Eclipse E4 RCP application, which runs with Java 7, I have the problem that the shutdown-hook is not executed when Windows (7) is shutting down or logging off.
After some research I found the following Open JDK bug entry, which creates an empty Swing JFrame and uses a shutdown-hook. The shutdown hook creates a file and writes to it. Although the bug is not directly related to my problem, I took the code and modified it a bit (see below). (The biggest modification is that it does not sleep in the hook.)
Afterwards I created a jar from that code and executed it with javaw -jar jarname.jar
. Then I tried logging off and shutting down and in both cases the expected file was written.
Afterwards I modified the code such that it creates an empty SWT Shell and uses the same shutdown-hook (see also below). When logging off and shutting down the expected file is not written.
Now I am wondering why the behavior is so different? I find it especially hard to find current information about Windows and the shutdown hook.
Furthermore, how can I ensure that the shutdown-hook is executed in my RCP application?
public class ShutdownHookSwingBug {
public static final String fileName = "C:/shutdownhookbug_swing.log";
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
File myFile = new File(fileName);
myFile.delete();
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
try {
// Write "Hello " to a file
File myFile = new File(fileName);
FileOutputStream outputStream = new FileOutputStream(myFile);
outputStream.write("Hello ".getBytes());
outputStream.flush();
// Write "world!" and close the file
outputStream.write("world!".getBytes());
outputStream.flush();
outputStream.close();
} catch (Exception e) {
// Shouldn't happen.
}
}
});
}
}
public class ShutdownHookSwtBug {
public static final String fileName = "C:/shutdownhookbug_swt.log";
public static void main(String[] args) {
Display display = new Display();
Shell shell = new Shell(display);
shell.setSize(300, 300);
File myFile = new File(fileName);
myFile.delete();
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
try {
File myFile = new File(fileName);
FileOutputStream outputStream = new FileOutputStream(myFile);
outputStream.write("Hello ".getBytes());
outputStream.flush();
outputStream.write("world!".getBytes());
outputStream.flush();
outputStream.close();
} catch (Exception e) {
// Shouldn't happen.
}
}
});
shell.open();
while(!shell.isDisposed()){
if(!display.readAndDispatch()){
display.sleep();
}
}
display.dispose();
}
}
Upvotes: 3
Views: 355
Reputation: 1179
As a workaround I am using the following code in my E4 RCP application:
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(false);
}
});
But I am not happy with it because:
Upvotes: 2