Java Swing application terminates unexpectedly

I am trying to write a Swing application in Java that also runs the Google AppEngine Dev server (see Developing a Java application using the AppEngine database ) and I came across a strange problem with Swing Eventloop.

I have the following two classes:

A debug window that will eventually receive log messages, etc .:

public class DebugWindow { private static JFrame debugWindow = null; private static JTextArea debugContent = null; public static void show() { debugWindow = new JFrame("Debug"); debugWindow.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); debugContent = new JTextArea("Debug messages go here!"); debugWindow.add(debugContent, BorderLayout.CENTER); debugWindow.pack(); debugWindow.setVisible(true); } } 

Helper class that loads Google AppEngine Dev-Server:

 // other imports import com.google.appengine.tools.development.DevAppServerMain; public class DevServer { public static void launch(final String[] args, boolean waitFor) { Logger logger = Logger.getLogger(""); logger.info("Launching AppEngine server..."); Thread server = new Thread() { @Override public void run() { try { DevAppServerMain.main(args); // run DevAppServer } catch (Exception e) { e.printStackTrace(); } } }; server.setDaemon(true); // shut down server when rest of app completes server.start(); // run server in separate thread if (!waitFor) return; // done if we don't want to wait for server URLConnection cxn; try { cxn = new URL("http://localhost:8888").openConnection(); } catch (IOException e) { return; } // should never happen boolean running = false; while (!running) { try { cxn.connect(); // try to connect to server running = true; } catch (Exception e) {} } logger.info("Server running."); } } 

My main(...) method looks like this:

 public static void main(final String[] args) throws Exception { DevServer.launch(args, true); // launch and wait for AppEngine dev server SwingUtilities.invokeLater(new Runnable() { @Override public void run() { DebugWindow.show(); // create and show debug window } }); } 

With this, I get very strange behavior regarding Swing Eventloop:

  • Firstly, the way Swing works: if I comment out the line DevServer.launch(...) in main(...) , the application starts, shows the debug window, continues to work, and when I close the debug window, it will turn off.
  • If I add DevServer.launch(...) back, it will start the server as expected and then stop working immediately (it will probably also show a debug window, but it is too fast to see).
  • If I move the line DevServer.launch(...) after SwingUtilities.invokeLater(...) , it displays a debug window, then it starts the server, and when the server shuts down, it immediately shuts down.
  • Now it looks very strange: if I changed the line to DevServer.launch(args, false) , that is, I do not wait for the server to start, but just let my main(...) method execute immediately, the debug window will appear, the server is loading correctly, The application continues to work, but does not exit if I close the debug window ?!
  • If I then change JFrame.DISPOSE_ON_CLOSE to JFrame.EXIT_ON_CLOSE , the debug window shows that the server is loading correctly, the application continues to work, and it quits if I close the debug window.

Any idea what happens to the Swing event loop here? I'm at a standstill ... Are there any things that will cause the Swing event loop to complete earlier (scenarios 2 and 3)? Do multi-threaded applications prevent Swing from discovering the last remote window (script 4)?

For reference, here is the source of the Google AppEngine Dev Server .

+4
source share
1 answer

Positions # 4 and # 5 are the expected behavior. A Java / Swing application does not stop when the last Swing window is located, but when the last thread stops execution. These two conditions are equivalent for single-threaded applications, but not for multi-threaded ones.

As for # 1, # 2 and # 3: looking through the AppEngine Dev server code, I noticed a lot of System.exit(int) calls there. One of them is probably the culprit. If the code you show has all the meaning, then the offensive System.exit will most likely be called in response to the connection established after if (!waitFor) return; (because of # 4)

+1
source

Source: https://habr.com/ru/post/1492447/


All Articles