« Dogfood | Main | New Swing Features in Groovy 1.5 »

More reasons I am leaving NetBeans for IntelliJ

Check out this beauty, any decent Swing developer should cringe at this stack trace

java.lang.Object.wait(Native Method)
java.lang.Object.wait(Object.java:485)
org.netbeans.modules.debugger.jpda.JPDADebuggerImpl.waitRunning(JPDADebuggerImpl.java:290)
org.netbeans.modules.debugger.jpda.JPDADebuggerImpl.finish(JPDADebuggerImpl.java:1039)
org.netbeans.modules.debugger.jpda.actions.KillActionProvider.doAction(KillActionProvider.java:74)
org.netbeans.api.debugger.ActionsManager.doAction(ActionsManager.java:158)
org.netbeans.api.debugger.Session.kill(Session.java:278)
org.netbeans.modules.debugger.ui.models.SessionsActionsProvider$3.perform(SessionsActionsProvider.java:97)
org.netbeans.spi.viewmodel.Models$ActionSupport.actionPerformed(Models.java:528)
javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995)
javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318)
javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
javax.swing.AbstractButton.doClick(AbstractButton.java:357)
javax.swing.plaf.basic.BasicMenuItemUI.doClick(BasicMenuItemUI.java:1216)
javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(BasicMenuItemUI.java:1257)
java.awt.Component.processMouseEvent(Component.java:6038)
javax.swing.JComponent.processMouseEvent(JComponent.java:3265)
java.awt.Component.processEvent(Component.java:5803)
java.awt.Container.processEvent(Container.java:2058)
java.awt.Component.dispatchEventImpl(Component.java:4410)
java.awt.Container.dispatchEventImpl(Container.java:2116)
java.awt.Component.dispatchEvent(Component.java:4240)
java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4322)
java.awt.LightweightDispatcher.processMouseEvent(Container.java:3986)
java.awt.LightweightDispatcher.dispatchEvent(Container.java:3916)
java.awt.Container.dispatchEventImpl(Container.java:2102)
java.awt.Window.dispatchEventImpl(Window.java:2429)
java.awt.Component.dispatchEvent(Component.java:4240)
java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273)
java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)
java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:173)
java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)
java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160)
java.awt.EventDispatchThread.run(EventDispatchThread.java:121)

Yes, Netbeans totally froze up on me, because some overworked programmer thought it would be good to do a blocking wait without timeout in the Swing Event Dispatch Thread. If a single problem happens you are stuck in limbo forever. Which is why non-timeout wait calls can be so evil, and doing it in the EDT makes it demonic. Looks like we need to get the stick back out, or punish whoever it is that violated their blood oath.

Really, I'm not just being petty. I've sent may stack traces like this to the bugzilla at NetBeans for years, literally years, and they still are doing messed up things in their action handlers without checking to see if they are in the EDT. It may have the best GUI designer for Java out there, but the frosting doesn't matter if you cannot stomach the cake.

Comments (5)

Martin Entlicher:

Much more efficient than blog about this would be to submit the problem into NetBeans' Issuezilla at http://www.netbeans.org/community/issues.html and it would be handled accordingly.

This is definitely not a standard behavior, the debugger got stuck on something (full thread dump would be necessary to identify why notify() was not called, some other thread is also likely blocked by something). You have run into a problem that occurs quite rarely IMHO. Bugs like this do happen and nobody made a blocking call in AWT intentionally. NetBeans is a highly multi-threaded program and the code paths are not always that obvious.

Regards,
Martin Entlicher

Danno Ferrin [TypeKey Profile Page]:

You missed the point of my post. I have posted stack traces like these to Bugzilla for far too long (and I have seen these freezes in many different places) and the programmers still don't get it. The feature developers don't care if they are in the EDT or not when they get the handoff to start doing work. Another bug is where I have seen 6.0 generation builds go into CVS and do a full tree status lookup all in the EDT! Posing in Bugzilla is apparently as or less effective than flaming them in a blog post. It still happens way to often. (And just once is too often).

"You missed the point of my post. I have posted stack traces like these to Bugzilla for far too long (and I have seen these freezes in many different places) and the programmers still don't get it."

I get the point of your post. I think the next real advance in programming languages will be one that makes it hard to do concurrent programming wrong. That will be the Java-killer language (there are ones today, but having played with Concurrent Clean, well, doing stateful UI in a language where everything is an argument is a major impedance mismatch). In fact (given that Javascript is a wretched bucket of turds), the one value of everybody learning AJAX is that you're doing the equivalent of desktop programming but there's no escape from the notion that you *have* to call stuff asynchronously and handle the asynchronicity of it. In a perfect world, a UI toolkit handles events and painting and that's it, and you shuffle off all other work onto a background thread - BUT, on single CPU machines, the cost of context switching is high enough that most of the time it really is better to run your logic synchronously than incur the cost of lots of context switching. So with AJAX, much as I detest a lot of it, it is finally really separating the event-handling and logic layers, because there invoking the logic is really high cost (the cost being either a round trip to the server or having to write incredibly fragile code for the client). IMO that might be the only real benefit AJAX has to offer :-/

Anyway, just this weekend I helped a friend who had an inexplicable performance problem in a Swing app - it turned out he was using java.net.URL's as domain objects, and adding them to a collection - and URL.equals will open a socket connection to figure out if it routes to the same IP address as another URL (okay, that is pure evil). The point being there are a lot of ways to create a full-on or temporary deadlock, and we've all done that sort of thing, so we're all in glass houses here.

To a point...ANYBODY writing code that does expensive I/O operations, if they are sane, should do two things that will save a lot of pain later: 1. Wrap all I/O in the equivalent of a runnable so it can be logged, and encourage users of the API to override toString(). With generics you can do as many typed arguments as you need pretty simply. 2. Any call that does slow I/O should have its first line be assert !EventQueue.isDispatchThread() so you catch blocking the UI early and fix it before anything ends up in production code.

-Tim

Danno Ferrin:

But what bothers me the most is that NetBeans has some perfect places to insure that actions are handled out of band, and yet it doesn't. When you over-ride an actionPerformed dispatch, you can add add in code that will dispatch it to a back end task unless specifically told not to. The default should be to not do actions in the EDT.

IntelliJ hasn't frozen the GUI yet. And I've done some abusive things to it as an end user. You can whine all day about how hard concurrent programming is but all that will do is automate the principle rule of how you should deal with the EDT. You are either (a) reading GUI widget state, (b) writing GUI widget state, or (c) getting out of the EDT. It's when these rules are violated that problems occur.

Danno Ferrin [TypeKey Profile Page]:

Notice that no one is defending the practice of calling Object.wait() instead of calling Object.wait(long) and dealing with the timeout? Honestly, if it wasn't for that feature I would just be silently switching to IntelliJ instead of continuing to beat this dead horse. Perhaps the NetBeans team should audit their code for all instances of infinite waits and purge them.

Post a comment


About

This page contains a single entry from the blog posted on December 5, 2007 3:00 PM.

The previous post in this blog was Dogfood.

The next post in this blog is New Swing Features in Groovy 1.5.

Many more can be found on the main index page or by looking through the archives.

Powered by
Movable Type 3.33