gillesB
gillesB

Reputation: 1179

Different shutdown-hook behavior on Windows shutdown

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?

Swing code

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.
        }
      }
    });
  }
}

SWT code

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

Answers (1)

gillesB
gillesB

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:

  • I have no idea why it works
  • I am mixing Swing into a pure SWT application

Upvotes: 2

Related Questions