JConsole, let me introduce you to SwingWorker
Today when I was using JConsole I noticed that when I tried to connect to a process the UI was hanging. The application that it was trying to connect to was not in a good state, but I was surprised at the lack of a responsive UI. Curious, I captured a thread dump and saw this gem:
"AWT-EventQueue-0" prio=6 tid=0x0100cd00 nid=0x899e00 runnable [0xb0d13000..0xb0d14d90] at java.net.PlainSocketImpl.socketConnect(Native Method) at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333) - locked <0x2559e880> (a java.net.SocksSocketImpl) at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195) at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182) at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:432) at java.net.Socket.connect(Socket.java:520) at java.net.Socket.connect(Socket.java:470) at java.net.Socket.(Socket.java:367) at java.net.Socket. (Socket.java:180) at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(RMIDirectSocketFactory.java:22) at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(RMIMasterSocketFactory.java:128) at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:569) at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:185) at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:171) at sun.rmi.server.UnicastRef.newCall(UnicastRef.java:306) at sun.rmi.transport.DGCImpl_Stub.dirty(Unknown Source) at sun.rmi.transport.DGCClient$EndpointEntry.makeDirtyCall(DGCClient.java:328) at sun.rmi.transport.DGCClient$EndpointEntry.registerRefs(DGCClient.java:275) at sun.rmi.transport.DGCClient.registerRefs(DGCClient.java:112) at sun.rmi.transport.LiveRef.read(LiveRef.java:277) at sun.rmi.server.UnicastRef2.readExternal(UnicastRef2.java:54) at java.rmi.server.RemoteObject.readObject(RemoteObject.java:438) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:585) at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:946) at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1809) at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1719) at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1305) at java.io.ObjectInputStream.readObject(ObjectInputStream.java:348) at javax.management.remote.rmi.RMIConnector.findRMIServerJRMP(RMIConnector.java:1871) at javax.management.remote.rmi.RMIConnector.findRMIServer(RMIConnector.java:1789) at javax.management.remote.rmi.RMIConnector.connect(RMIConnector.java:259) - locked <0x25600378> (a javax.management.remote.rmi.RMIConnector) at javax.management.remote.JMXConnectorFactory.connect(JMXConnectorFactory.java:248) at javax.management.remote.JMXConnectorFactory.connect(JMXConnectorFactory.java:207) at sun.tools.jconsole.ProxyClient. (ProxyClient.java:156) at sun.tools.jconsole.ProxyClient.getProxyClient(ProxyClient.java:57) at sun.tools.jconsole.ConnectDialog.actionPerformed(ConnectDialog.java:342) at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1882) at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2202) at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:420) at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:258) at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236) at java.awt.Component.processMouseEvent(Component.java:5602) at javax.swing.JComponent.processMouseEvent(JComponent.java:3135) at java.awt.Component.processEvent(Component.java:5367) at java.awt.Container.processEvent(Container.java:2010) at java.awt.Component.dispatchEventImpl(Component.java:4068) at java.awt.Container.dispatchEventImpl(Container.java:2068) at java.awt.Component.dispatchEvent(Component.java:3903) at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4256) at java.awt.LightweightDispatcher.processMouseEvent(Container.java:3936) at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3866) at java.awt.Container.dispatchEventImpl(Container.java:2054) at java.awt.Window.dispatchEventImpl(Window.java:1801) at java.awt.Component.dispatchEvent(Component.java:3903) at java.awt.EventQueue.dispatchEvent(EventQueue.java:463) at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:269) at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:190) at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:180) at java.awt.Dialog$1.run(Dialog.java:535) at java.awt.Dialog$2.run(Dialog.java:565) at java.security.AccessController.doPrivileged(Native Method) at java.awt.Dialog.show(Dialog.java:563) at java.awt.Component.show(Component.java:1302) at java.awt.Component.setVisible(Component.java:1255) at sun.tools.jconsole.ConnectDialog.setVisible(ConnectDialog.java:415) at sun.tools.jconsole.JConsole.showConnectDialog(JConsole.java:583) at sun.tools.jconsole.JConsole.access$100(JConsole.java:34) at sun.tools.jconsole.JConsole$4.run(JConsole.java:702) at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209) at java.awt.EventQueue.dispatchEvent(EventQueue.java:461) at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:269) at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:190) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:184) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:176) at java.awt.EventDispatchThread.run(EventDispatchThread.java:110)
Every Swing programmer that has gotten past Hello World knows that this is a no-no. AWT and Swing components are rendered by a single thread, and if that thread gets blocked then you end up with an unresponsive UI. Clearly there should never be any network code in the stack trace of the AWT event thread. This is on the 1.5 VM on OS X so I don’t know if Sun or Apple is to blame (I assume Sun), but if this isn’t fixed yet in 1.6 then they should review the Swing Tutorial:
Tasks on the event dispatch thread must finish quickly; if they don’t, unhandled events back up and the user interface becomes unresponsive.