Background
Nailgun is a utility (server-protocol-client) for sending java applications to a server with the purpose of reducing the start up time of the VM.
Problem
A vary basic swing application fails to launch through nailgun. The application exits between the lines marked with “NG 1” and “NG 1.1”, when calling setDefaultCloseOperation. The server prints this:
NGSession 2: 127.0.0.1: org.genja.volumeslider.Aframe exited with status 0
If I comment out the close-operation method of JFrame, the frame shows as it should.
Code
package org.genja.volumeslider;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.imageio.*;
import java.util.*;
import java.io.*;
public class Aframe {
public static void main(String[] argv) {
System.out.println("NG 1");
JFrame frame = new JFrame("VolumeSlider");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
System.out.println("NG 1.1");
frame.setPreferredSize(new Dimension(64,200));
frame.setResizable(false);
JSlider slider = new JSlider(JSlider.VERTICAL, 0, 55, 12);
frame.add(slider, BorderLayout.CENTER);
//Display the window.
frame.pack();
frame.setVisible(true);
}
}
Question
What can be causing this? Is this a bug in nailgun, or should I use some other way of enabling the close button in swing/java? I think it’s relevant to mention that the applications does exit without problems (x button works) even if the class is run through nailgun, without setting the default close operation (perhaps nailgun does this somehow?).
I am fairly confused at this point, and any suggestions would be useful.
update:
It seems also that the keylistener gets KeyEvents that are not properly configured. I’m experiencing that numerical keys still get through when switch-cased with KeyEvent.VK_[0-9], but keys such as VK_ESCAPE and VK_Q do not seem to match. I should probably just look at the “raw” code they generate in that VM and match against that as opposed to the KeyEvent.VK_* constants. Reasonable?
Nailgun author here.
Andrew’s instinct is exactly right. Nailgun uses a SecurityManager to prevent one class’s System.exit() from killing the whole Nailgun VM.
If you set the default close operation to EXIT_ON_CLOSE then closing the window would shut down the VM and prevent future invocations, which I’m guessing you don’t want to prevent.
A quick check of the openjdk source for JFrame confirms that the System SecurityManager’s checkExit() method is called when you call setDefaultCloseOperation(EXIT_ON_CLOSE). This is where your app is dying. You may also see a com.martiansoftware.nailgun.NGExitException as a result.
It’s nice that JFrame checks for the exit permission when you set the default close operation rather than when it tries to exit – at least it made this easy to find! 🙂