This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.
Deadlock in IDE appears when you try to show a JSP in Swing HTML Browser. It started to happen from build 200206250100. It worked correctly in build 200206240100. Tested on JDK1.4.0. Steps to reproduce: - start IDE - in the Setup wizard choose Swing HTML Browser as your default web browser - create JSP from template - choose "Execute" from popup menu - commit "Question" and "Information" dialogs - after while IDE freezes (see attached thread dump)
Created attachment 6430 [details] Thread dump
No, it's not SwingBrowser. The brower is waiting for data from Tomcat but the data never come. Web module please investigate.
This deadlock occured due to changes in OutputTabTerm, which now calls invokeAndWait. Not a classic deadlock, Thread 21 is waiting for Compilation thread, Compilation thread waits through OutputTabTerm for AWT thread, AWT thread waits (externally, in native method) for socket read, which is probably being held by thread 21, handling connection.
Yes, looks that this is really regression due to changes in OutputTerm. 1) Swing browser tries to read response code of displayed HTML page (ugly behaviour implemented in JDK that allows to redirect HTML pages correctly). Thus it waits for data provided from JSP page processing. 2) JSP page that is processed in Tomcat has to be compiled. This is done by call to IDE where org.netbeans.modules.tomcat40.autocompile module performs real compilation. This requires some lock related to compiler. 3) Output term holds it and wants to print output of Tomcat processing (there is a bunch of messages on startup) but can't access AWT queue. So I guess we should reconsider the changes in OutputTerm
Issue #25202 is probably related. I agree that the use of SwingUtilities.invokeNow is dangerous here, since Term cannot know who is calling it. Admittedly there is bad scripting-module code in issue #25202, and ugly Swing code here, but at least the Swing code we cannot change, so we have to make Term safer.
I agree with Jesse. Small comment to swing browser: although we can't change JDK code we may attempt to workaround it in a similar way as when debugger running. In sush case we don't try to get response code. Disadvatage is that we don't support forwading, set mime type to text/html and don't process info about locale.
Created attachment 6466 [details] Thread dump
I have added thread dump of deadlock resulting from using scripting console in today's build. I don't think it is a fault of scripting module and I hope that it is relevant to this bug report.
Ivan, if you're going to fix it before vacations, please commit your fix in branch QBE200206260100 (Q-Build Emergency).
Using invokeAndWait is wrong in OutputTabTerm - please study a deadlock I have attached to this bug report. The scenario is quite easy to reproduce: 1. someone tries to call Throwable.printStackTrace (from non-AWT thread) --> it locks on the output stream (System.err) 2. invokeAndWait is called while holding the lock 3. someone wants to access System.err from AWT thread --> deadlock From this I conclude that OutputTabTerm$OutTermPane$TermOutputWriter.write should be non-blocking. Following test should print a stack trace 11x. If I use internal execution it is 100% deadlock on my machine. import javax.swing.SwingUtilities; public class DeadlockTest { public static void main(String[] args) { Runnable r = new Runnable() { public void run() { new Exception().printStackTrace(); } }; for (int i = 0; i < 10; i++) { SwingUtilities.invokeLater(r); } final Thread t = new Thread(r); t.setPriority(Thread.MAX_PRIORITY); t.start(); } }
I have commited a temporary fix to OutputTabTerm that calls invokeLater instead of invokeAndWait. Please revisit and find a better fix.
I can't get Davids last example (with the postponed exception) to lock up but I looked at the two attached stack traces. On the JSP deadlock. What I see is the event dispatcher ultimately calling a read(). Now read() is a system call that blocks indefinitely. It is not the sort of thing that should be called from a thread which is only allowed to do quick things. I also don't believe it's neccessarily a Swing problem. It _is_ org.openide.awt.SwingBrowserImpl$SingBrowser that's calling the getStream() that's causing the blockage! Should it really do this? On the scripting deadlock. The cause there is actually the 'synchronized' in appendText. That was added because parallel err and output streams were vying for a single buffer. We should be able to retain the main invokeAndWait() and just get rid of this synchronized. Because it's tied to stderr and stdout coming in parallel I suspect Davids little example is also suffering from this. Since I can't reproduce it could verify this please David? I.e. temporarily add in the invokeAndWait(), and take out the synchronized and see what happens. On Davids temporary fixes. They are incomplete. You cannot get a character array that comes in and pass it on to an invokeLater. You need to make a _copy_ of it. Otherwise you'll get scenarios where some output is missing and some output is duplicated. I'll try and commit this tonight.
Added code to the implementations of OutputWriter which use invokeNow() so they make copies of strings or character arrays for each Runnable closure. Added a final boolean safe_mode = true to simplify switching back and forth.
Created attachment 6495 [details] Deadlock with safe_way = false
With safe_way = true the deadlock does not occur. Should I try something more?
A code-review of OutputWriter method overrides where I make copies of buffers, would be nice. I"m more concerned abpout that http connection in the AWT thread. It has potential to cause trouble elsewhere and I'd like to see it addressed. Also, did you try to remove the 'synchronized' from the append text? and see if the second deadlock goes away? (note: if you are in safe mode that synchronized needs to be there, so if you want to test make sure to set safe_mode to false). I ultimately want to get back to using invokeAndWait().
> I ultimately want to get back to using invokeAndWait() Be careful, very careful. IMO invokeAndWait() is evil. If we use it we cannot know for sure that the situation like the one happened in this bug won't happen. I am closing this bug as FIXED, because it's fixed. We can continue the discussion here to find a better fix if we desire. But please do it for the next release (4.0). It's too late for 3.4 (because I suspect the code change won't be trivial)
Verified in build 200207100100.
Resolved for 3.4.x or earlier, no new info since then -> closing.
moving terminal emulator issues to terminalemulator component. To see the correct version and target milestone of this issue look at Issue Activity table.