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.
In in application using the netbeans platform the following assertion is thrown from time to time during program start: java.lang.IllegalStateException: Assertion failed. WindowsAPI is required to be called from AWT thread only, see http://www.netbeans.org/download/dev/javadoc/OpenAPIs/org/openide/doc-files/threading.html at org.netbeans.core.windows.WindowManagerImpl.assertEventDispatchThreadWeak(WindowManagerImpl.java:1142) at org.netbeans.core.windows.WindowManagerImpl.getMainWindow(WindowManagerImpl.java:131) at org.netbeans.core.NonGui$3.run(NonGui.java:212) at java.awt.event.InvocationEvent.dispatch(Unknown Source) at java.awt.EventQueue.dispatchEvent(Unknown Source) at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source) at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source) at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.awt.EventDispatchThread.run(Unknown Source)
Where is the rest of exception stack trace ? I guess it should contains the name of the class, that is calling WindowdAPI from the outside of AWT thread. Dafe, Am I right ?
The stack trace I sent is complete. I had a look into the code and I think that you can't expect a longer stack trace. The reported exception is created in WindowManagerImpl.java at line 1142 and the stack trace goes up to the run method of the EDT. I also had a look at the main window initialization in NonGui.java (starting at line 151). It seems to me that there is a possible race condition in this rather complex method (which I did not fully understand). In line 165 a new thread is started. This thread will (when it is running) exchange the system event queue. In the meantime an awt timer is started and the line WindowManager.getDefault().getMainWindow() is executed in the EDT. I'm not sure about the consequences when getMainWindow() is called before the EventQueue has been exchanged in contrast to what will happen if the exchange of the EventQueue happens first. Best regards, Martin
Passing to Jarda, author of the code which seems to run winsys outside of EQ thread.
Dafe, it is true that code that I have reformmated calls WindowManager.getMainWindow, but it does so inside of SwingUtilities.invokeLater - which is imho the proper way to do it. Maybe your assert is incorrect?
No, assert in winsys seems to be OK: if(!SwingUtilities.isEventDispatchThread()) ... Please read comments form mgoe...
mgoe talks about race condition - however I have no clue how a race condition can cause assert like this to fail. If it can, then it is race condition in AWT as it produces wrong result from SwingUtilities.isEventDispatchThread(), isn't it?
As the reporter of this bug I would like to direct your attention to a fact that I discovered while playing with EventQueue exchange. I found out that calling Toolkit.getDefaultToolkit().getSystemEventQueue().push(new EventQueue()) will not only replace the current EventQueue but will also replace the EventDispatchThread. In my tests before pushing the new EventQueue the EventDispatchThread was AWT-EventQueue-1. After I pushed the new EventQueue the EventDispatchThread was AWT-EventQueue-2. That means that code which is executed in the EventDispatchThread and pushes a new EventQueue will no longer be executed in the EventDispatchThread once the change of the EventQueue has happened. I think that this happens in the method initializeMainWindow() (NonGui.java:151): <Some code in the EDT> <Start Runnable pushing new EventQueue> <Some code which no longer runs in the EDT when the run() method of the Runnable pushing the new EventQueue has been executed.> After pushing a new EventQueue the only thing which seems to be safe is invokeLater(). Best regards, Martin
Jarda please cc yourself next time so you can watch the comments...you always immediatelly returns the issue to me without listening further :-( I also think that exchanging EQ thread causes the problem, like reporter suggested. How could I do something with it in winsys? I simply can't...
Further investigation of the problem showed that it is most likely a threading issue in the JDK. Please see my bug report: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6542185
mgoe, thank you for your effort. Closing with link to the JDK bug.
Hello, its me again. Unfortunately your colleagues closed my bug as "not a bug". Perhaps you can talk to them to reconsider their decision. Best regards, Martin Goettlicher
I'll try to dig in it, hopefully next week.
Jesse, could you shed some light on our code in NonGui.initializeMainWindow and help me to find out if this is really JDK bug or ours? We are doing something like: initializeMainWindow { // method executed off EDT doSomething() EventQueue.invokeAndWait( new Runnable() { // we actually use Mutex.EVENT.writeAccess public run() { EventQueue.push() } } EventQueue.invokeLater( new Runnable() { public run() { EventQueue.isEventDispatchThread(); <--- returns false, wrong! } } } My view is that it's clear JDK bug, reporter mgoe even wrote test case and filed JDK bug http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6542185, but JDK guys keep closing it... Perhaps Jesse you can explain our motivation for doing EventQueue.push and help me convince JDK guys :-) thank you.
Well I know nothing about #6542185 - this is the first I have heard of it. I don't really understand the problem there well enough to comment on it. The use of EventQueue.push is a workaround for http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4786277 which was closed as not a bug over my protests. (It is a regression from 1.3; timing-dependent but reproducible after one second; and clearly a mistake, when you examine what the code is trying to do.) Perhaps we need a different workaround, or need to escalate #4786277.
Well, as a representative of Dark forces (AWT team) I will try to help you to understand our (AWT position). Let's start from previous comment from dsimonek: 6542185 was closed because it complains about three different things: first two are known bugs and the third is not a bug. 1. a deadlock - duplicate of 4943231 2. we do not reuse EDTs - duplicate of 6424157 3. at some points user may see several threads with name "AWT-EventQueue-*" - not a bug, existence of several threads is not a bug, it would be bug if AWT treats several of them as current EDT (but there was no information about this). As for piece of code which shows possible problem it would be nice to have more information: - how often the problem is reproducible - is it possible to provide a stand-along test case No about comment from jglick: as far as I understand 4786277 is about the fact that re-created EDT doesn't restore the latest class loader which was set on previous one. (Please correct me if I'm wrong) If I've got it correctly then I agree with an engineer that NB used some internal knowledge about AWT which is not a part of specification. And I'd also suggest you to request some new API which will serve your needs (have you filed such rfe? if yes, please let me know its #) Hope I've explained some actions we've done and really want to continue the discussion to finally resolve this issue.
To point 3 of the posting of olegsukhodolsky I would like to annotate that I did not complain that there is more than one thread called "AWT-EventQueue-*". What I tried to explain is that when a new EventQueue has been pushed/popped (from time to time) there is more than one thread working on the EventQueue. That these threads are called "AWT-EventQueue-*" is not relevant for the problem. Relevant is, that more than one thread is working on the EventQueue. In our product which is based on the netbeans rich client platform this leads to the problem described in this bug report (java.lang.IllegalStateException: Assertion failed. WindowsAPI is required to be called from AWT thread only) and to the problems described in my jdk bug report (http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6542185). Best regards, Martin
Hi Martin, it is nice to hear your opinion, it was one of the reasons why I asked to continue this discussion in IssueZilla (current bug database for jdk is not very convenient for this :( I have to say that I have interpreted your bug incorrectly (not that same way as you want to :( Partially because there are a lot of information (and it is easy to miss something, partially because the test informs that there a several threads with specific name, but does not try to reproduce the problem which is described here. So, several questions for you: - how often/easy the problem can be reproducible? - have you been able to write simple test case (better stand-along, but even one which uses NetBeans platform will be ok)? Thanks, Oleg.
Hello Oleg, using the code in http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6542185 the problem can be reproduced quite often (it is more likely on multi core/processor machines). In netbeans or in applications based on the rich client platform the problem does not happen that often. In order to better trace the problem in the netbeans platform I would suggest to add some code at the place where the message "java.lang.IllegalStateException: Assertion failed. WindowsAPI is required to be called from AWT thread only" is printed. This code should print the current thread (which is not the EDT when this message is printed) and the list of threads running (it would be nice if an api would exist in the jdk to get the current EDT). Then you will see that a thread called "AWT-EventQueue-*" for which EventQueue.isEventDispatchThread() returns false will process events from the EventQueue. Because this netbeans platform startup issue does not happen very often I have written the example in bug 6542185. As I said above this example shows the problem quite often and has more severe consequences (NPE in swing code or deadlock) which we also observe in our application while trying to display a shutdown progress dialog from the close() method of a class extending ModuleInstall. Because the close() method is called from the EDT an own EventQueue has to be used to keep the progress dialog alive. For us it is very important that this issue is resolved. So please don't hesitate to contact me if I could assist you in solving the problem. Best regards, Martin PS: I will attend the netbeans day and the JavaOne.
I may be wrong, but I think that the deadlock is the same as in 4943231. And if I'm right then the threading issue you are complaining about is not the root cause of the deadlock. I can be reproduced w/o any pop, just two pushes and "luck" :) As for situation when two different threads process events: it may be possible, but I need to reread/evaluate our code and meditate some time to find the truth :), because I'm unable to reproduce this :( do not have multi processors system) I'll update this issue as soon as find something (feel free to ping me, if it takes too long ;) Thanks, Oleg. P.S. I'll be far far away from San Francisco in may :(
"4786277 is about the fact that re-created EDT doesn't restore the latest class loader which was set on previous one." - right. EQ *does* restore the latest class loader if a new EQ is pushed within a second; it has code explicitly written to do so (EQ.classLoader). But that code is buggy: it fails to consider the fact that as of JDK 1.4, inactive EventDispatchThread's are collected after a second by AWTAutoShutdown. You can easily see the problem with the test case I provided in that bug report. The result is that in NB, where we require that a particular application-specific context class loader be set on all threads, if there are usages of EQ during startup (before the main window is shown) there is a problem if and only if at least one second passes with no EQ activity. Our workaround is to push a new event queue during startup so we always have one active, thus ensuring that its CCL is never "lost". Another possible workaround might be to set a timer to go off every half-second during startup (before main window) and to forcibly set the CCL on the current EQ thread. Still subject to race conditions since the timer thread might be starved, but perhaps this is the best we can do. "I'd also suggest you to request some new API which will serve your needs" - well, an API is useless to us. We cannot afford to wait for JDK 7 for our IDE to work correctly. If you don't want to support maintenance of the class loader on the EQ thread at all, then please remove the current code which tries to do so and fails; at least the behavior of AWT would not then be timing-sensitive, which would be an improvement. (In fact if this obsolete EQ.cL field were deleted, we would probably not have the problem to begin with, since we set the right CCL on all threads at once sometime during startup - the original problem arose when an EventQueue object created earlier, when the default CCL was still in effect, creates a new thread and sets the wrong CCL on it, rather than just inheriting the CCL from the parent thread in the usual way, which would have been fine.) BTW this issue should not be WONTFIX if there is no open JDK bug that is planned to be fixed (and backported) in the near future.
Created attachment 41611 [details] Test case showing an EDT violation in conjunction with EventQueue.push/pop
Hello Oleg, I created a new test case which I attached to this bug. It is based on the class CheckThreadViolationRepaintManager from the swinghelper project. It always shows an EDT violation when the progress dialog is closed. Please let me try to explain why I do something similar to the test case in our application. When the user has selected to exit our application (which is based on the netbeans rich client platform). The netbeans platform calls the close() method of a class extending ModuleInstall in the EDT. Because we need to do some timeconsuming operations in this close() method we wanted to give the user some feedback that there is still something going on. Since the application main window has been closed already by the platform we created a progress dialog. In order to keep this dialog alive we push a new EventQueue. Once our cleanup code is finished we pop this EventQueue and leave the close() method. I hope that this explains what we intend to do. Best regards, Martin
Hi Martin, why you do not use SwingWorker (or similar machinery) instead of EventQueue.push()/EventQueue.pop()? IMHO this is more safe wayt to implement the functionality you need. As for the test it reports violation because something is executed on the first EDT after your actionPrformed() completed, i.e. we have something like: actionPerformed() { eq.push(); doSomething(); eq.pop(); checkIfEDT(); // at this point current thread is not an EDT any more. } This particular problem is described in http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6424157 Thanks, Oleg.
answer to the comment from jglick: > "4786277 is about the fact that re-created EDT doesn't restore the latest > class loader which was set on previous one." - right. EQ *does* restore the > latest class loader if a new EQ is pushed within a second; it has code > explicitly written to do so (EQ.classLoader). But that code is buggy: it fails > to consider the fact that as of JDK 1.4, inactive EventDispatchThread's are > collected after a second by AWTAutoShutdown. You can easily see the problem > with the test case I provided in that bug report. I tend to agree with you that we have an issue in our code. Please file against AWT and we will discuss this issue there. > "I'd also suggest you to request some new API which will serve your needs" - > well, an API is useless to us. We cannot afford to wait for JDK 7 for our IDE Well, when I suggested that I meant that it would be nice if someone requested such API just after 4786277 was closed. > to work correctly. If you don't want to support maintenance of the class > loader on the EQ thread at all, then please remove the current code which > tries to do so and fails; at least the behavior of AWT would not then be > timing-sensitive, which would be an improvement. Based on my current understanding of the problem I'd say that NB itself should do nothing about this particular issue, because if you perform in a separate InvocationEvent then you will have no problems. You have problem if you have something like: methodExecutedOnEDT() { doSomething(); eq.push(); doSomething1(); } if doSomething1() believes that it is called on EDT then you will have problems. But if you have: EventQueue.invokeLater(new Runnable() { pulic void run() { eq.push(); } ) Or if the code you execute after push() remembers that it is not on EDT, then you should be in the safe position. Thanks, Oleg. (In fact if this obsolete EQ.cL field were deleted, we would probably not have the problem to begin with, since we set the right CCL on all threads at once sometime during startup - the original problem arose when an EventQueue object created earlier, when the default CCL was still in effect, creates a new thread and sets the wrong CCL on it, rather than just inheriting the CCL from the parent thread in the usual way, which would have been fine.) BTW this issue should not be WONTFIX if there is no open JDK bug that is planned to be fixed (and backported) in the near future.
Oleg, answer and question for you - - Unfortunately I'm not able to give you isolated test or reproduction case, as this issue never happened to me :-( - Is there any way how could we workaround the issue on NB side? Perhaps posting to EQ.invokeLater in a loop until EQ.isEventDispatchThread() finally returns true?
> - Unfortunately I'm not able to give you isolated test or reproduction case, as > this issue never happened to me :-( no problem, we have some tests (thanks to Martin) for now. > - Is there any way how could we workaround the issue on NB side? Perhaps posting > to EQ.invokeLater in a loop until EQ.isEventDispatchThread() finally returns > true? Well, you could, invokeLater() will help, but do you really need this? IMHO it is the app (which uses NB platform" who breaks your and it should be corrected.
Created attachment 41622 [details] Corrected test case showing EDT violation.
Hi Oleg, you are right. I changed my test case (please see the new attachment) but the problem persists. Using a SwingWorker as suggested does not work because I must not leave the close() method of the class extending ModuleInstall. When I leave the close() method the netbeans platform cleanup continues which terminates any running thread. Best regards, Martin
> Well, you could, invokeLater() will help, but do you really need this? > IMHO it is the app (which uses NB platform" who breaks your and it should be > corrected. Oleg, I think it could break also in NB itself randomly, as I understand Martin's application on the top of platform doesn't modify NB platform code, only timing is different because of completely different set of modules on startup.
Hi Martin, I see no difference with previous one (in terms of reported violations). I still have just one: EDT violation detected current thread Thread[AWT-EventQueue-0,6,main] javax.swing.JButton[,5,5,86x25,alignmentX=0.0,alignmentY=0.5,border=javax.swing.plaf.BorderUIResource$CompoundBorderUIResource@a56a7c,flags=296,maximumSize=,minimumSize=,preferredSize=,defaultIcon=,disabledIcon=,disabledSelectedIcon=,margin=javax.swing.plaf.InsetsUIResource[top=2,left=14,bottom=2,right=14],paintBorder=true,paintFocus=true,pressedIcon=,rolloverEnabled=true,rolloverIcon=,rolloverSelectedIcon=,selectedIcon=,text=Push Me,defaultCapable=true] at java.lang.Thread.getStackTrace(Thread.java:1426) at EventQueueFailure2$CheckThreadViolationRepaintManager.checkThreadViolations(EventQueueFailure2.java:197) at EventQueueFailure2$CheckThreadViolationRepaintManager.addDirtyRegion(EventQueueFailure2.java:187) at javax.swing.JComponent.repaint(JComponent.java:4714) at java.awt.Component.repaint(Component.java:2924) at javax.swing.plaf.basic.BasicButtonListener.stateChanged(BasicButtonListener.java:142) at javax.swing.AbstractButton.fireStateChanged(AbstractButton.java:1889) at javax.swing.AbstractButton$Handler.stateChanged(AbstractButton.java:2310) at javax.swing.DefaultButtonModel.fireStateChanged(DefaultButtonModel.java:333) at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:249) at javax.swing.plaf.basic.BasicButtonListener$Actions.actionPerformed(BasicButtonListener.java:287) at javax.swing.SwingUtilities.notifyAction(SwingUtilities.java:1636) at javax.swing.JComponent.processKeyBinding(JComponent.java:2844) at javax.swing.JComponent.processKeyBindings(JComponent.java:2879) at javax.swing.JComponent.processKeyEvent(JComponent.java:2807) at java.awt.Component.processEvent(Component.java:5815) at java.awt.Container.processEvent(Container.java:2058) at java.awt.Component.dispatchEventImpl(Component.java:4410) at java.awt.Container.dispatchEventImpl(Container.java:2116) at java.awt.Component.dispatchEvent(Component.java:4240) at java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1848) at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(DefaultKeyboardFocusManager.java:693) at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(DefaultKeyboardFocusManager.java:958) at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:830) at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:657) at java.awt.Component.dispatchEventImpl(Component.java:4282) at java.awt.Container.dispatchEventImpl(Container.java:2116) at java.awt.Window.dispatchEventImpl(Window.java:2429) at java.awt.Component.dispatchEvent(Component.java:4240) at java.awt.EventQueue.dispatchEvent(EventQueue.java:599) at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273) at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183) at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:173) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160) at java.awt.EventDispatchThread.run(EventDispatchThread.java:121) do you see something else? As for workaround, perhaps showing modal dialog + SwingWorker will help. Thanks, Oleg.
to dsimonek: >> Well, you could, invokeLater() will help, but do you really need this? >> IMHO it is the app (which uses NB platform" who breaks your and it should be >> corrected. > Oleg, I think it could break also in NB itself randomly, as I understand > Martin's application on the top of platform doesn't modify NB platform code, > only timing is different because of completely different set of modules on > startup. as far as I can see, Martin's application calls EventQueue.push()/pop() in "the close()" method (have no ideas what the method is, but it looks like it is called during shutdown) Thanks, Oleg.
Hi Oleg, you are right, my new example (EventQueueFailure2.java) shows the same failure, but as you can see in the code all calls to swing code after EventQueue.push are now made via EventQueue.invokeLater() which I think is correct code. If you still believe that my code is not a valid java program, please tell me where my error is. If my program is valid code, please reopen http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6542185. Best regards, Martin
Hi Martin, it is not your code which is trigger the violation :( You should remember that your actionPerformed() is the last item in long call stack, and there are a lot of code which will be executed after it returns (on the same thread with assumption that it is executed on EDT. This is the reason why EventQueue.push()/EventQueue.pop() should be used very carefully. I've modified your test to print not only the component and call stack, but also the thread on which a violation occurred, and this is an old EDT. Thus I still consider this problem as a duplicate of http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6424157 Thanks, Oleg. P.S. btw have you evaluated possibility to use modal dialog + SwingWorker combination?
"I tend to agree with you that we have an issue in our code. Please file against AWT and we will discuss this issue there." - I did; that was #4786277. It was closed as not a bug. "I'd say that NB itself should do nothing about this particular issue, because if you perform in a separate InvocationEvent then you will have no problems" - I guess this comment refers to Martin's problem, which from what I understand is some kind of side-effect resulting from our (over four-year-old) workaround. I don't think it's accurate, either, since the call to EQ.push occurs in its own Runnable, as you can see in NB sources: http://deadlock.netbeans.org/fisheye/browse/~raw,r=HEAD/netbeans/core/src/org/netbeans/core/NonGui.java AFAIK we still need some special workaround for #4786277 in NB code, whether or not this takes the form of the current usage of EventQueue.push in NonGui. Otherwise the symptoms of our issue #28536 would reappear.
Hi jglick, > "I tend to agree with you that we have an issue in our code. Please file > against AWT and we will discuss this issue there." - I did; that was #4786277. > It was closed as not a bug. Well, I'd prefer to not reopen bug which was closed several years ago. I'd prefer to work a new with bug to work with. > "I'd say that NB itself should do nothing about this particular issue, because > if you perform in a separate InvocationEvent then you will have no problems" > - I guess this comment refers to Martin's problem, which from what I > understand is some kind of side-effect resulting from our (over four-year-old) > workaround. I don't think it's accurate, either, since the call to EQ.push > occurs in its own as far as I understand the problem it is caused by user's code. Martin said that they call both push() and pop(). Imho, push() can not cause any threading issues if push() is the last call in an event processing code. > Runnable, as you can see in NB sources: > >http://deadlock.netbeans.org/fisheye/browse/~raw,r=HEAD/netbeans/core/src/org/netbeans/core/NonGui.java > > AFAIK we still need some special workaround for #4786277 in NB code, whether > or not this takes the form of the current usage of EventQueue.push in NonGui. > Otherwise the symptoms of our issue #28536 would reappear. As I said above I do not think your code causes any problems. Thanks, Oleg.
> As I said above I do not think your code causes any problems. Nope, NB code in NonGui *does* cause problems randomly for Martin the reporter, see the very first comment of this issue. I think now there are two slightly different problems - Martin's problem with close and test case that you refer to, but also original problem that is described in very first comment. I repeat, in NetBeans production code in NonGui.java after EQ.push we are calling EventQueue.invokeLater( new Runnable() { public run() { EventQueue.isEventDispatchThread(); <--- returns false, wrong! } } and we are getting false from EventQueue.isEventDispatchThread() within runnable started through EQ.invokeLater, which I thought should never happen and is the symptom of the bug.
> I think now there are two slightly different problems - Martin's problem with > close and test case that you refer to, but also original problem that is > described in very first comment. Well, perhaps it is time for Martin to confirm if there is a problem when only push() from NB code is invoked or not. (Of course it would be nice to have some test for this problem too :)
Hello, first I would like to thank for this valuable discussion. I wish the jdk bug reporting system would allow this too. I think dsimonek has given a good summary. For me there are indeed two different problems: 1) In in application using the netbeans platform the following assertion is thrown from time to time during program start: "java.lang.IllegalStateException: Assertion failed. WindowsAPI is required to be called from AWT thread only" This problem is caused by netbeans code (EventQueue.push() during platform startup). I cannot do anything against this because no own code is involved here. 2) During the termination of our program we need to perform some timeconsuming cleanup operations. In order to give the user some feedback I implemented a progress dialog using code similar to my test case (EventQueueFailure2.java) attached to this bug report. The cleanup is performed in the the close() method of a class extending ModuleInstall. The close() method is called by the netbeans platform from the EDT. I cannot leave the close() method before the cleanup is done (for example by using a SwingWorker). If I leave the close() method the platform continues with its shutdown procedure which kills the worker thread. To Oleg: I tried to use a modal dialog + SwingWorker and even a variant using paintImmediately but until now without success. I called setText/setProgress... but the new texts and the progress were not shown. Both problems seem to have the same causes: - Using EventQueue.push does not guarantee that events are processed by a thread for which EventQueue.isEventDispatchThread() returns true in all cases. - Code executed in the EDT which calls EventQueue.push, performs some swing operations using invokeLater and calls EventQueue.pop is no longer in the EDT when the EventQueue.pop method returns. I think it is extremely important that this is fixed because without a fix EventQueue.push/pop cannot be used. Best regards, Martin
> first I would like to thank for this valuable discussion. I wish the jdk bug > reporting system would allow this too. I hope that after JDK open-sourcing we will have something better than current system. > I think dsimonek has given a good summary. For me there are indeed two > different problems: I see, it looks like I've missed this :( > 1) In in application using the netbeans platform the following assertion is > thrown from time to time during program start: > "java.lang.IllegalStateException: Assertion failed. WindowsAPI is required to > be called from AWT thread only" > This problem is caused by netbeans code (EventQueue.push() during platform > startup). I cannot do anything against this because no own code is involved > here. can you provide any test for this? Also how often you see the problem? > To Oleg: I tried to use a modal dialog + SwingWorker and even a variant using > paintImmediately but until now without success. I called > setText/setProgress... but the new texts and the progress were not shown. could you, please, send (through email) me a test with which I could play and see what is wrong with it. (btw what jdk do you use?) >Both problems seem to have the same causes: > - Using EventQueue.push does not guarantee that events are processed by a > thread for which EventQueue.isEventDispatchThread() returns true in all cases. > - Code executed in the EDT which calls EventQueue.push, performs some swing > operations using invokeLater and calls EventQueue.pop is no longer in the EDT > when the EventQueue.pop method returns. Well, I'd say we have two independent problems here :) > I think it is extremely important that this is fixed because without a fix > EventQueue.push/pop cannot be used. Well, I agree that this problems should be fixed (though I'd prefer to not have push()/pop() in our API at all :) Thanks, Oleg.
Hi Martin, >> To Oleg: I tried to use a modal dialog + SwingWorker and even a variant using >> paintImmediately but until now without success. I called >> setText/setProgress... but the new texts and the progress were not shown. > > could you, please, send (through email) me a test with which I could play and > see what is wrong with it. (btw what jdk do you use?) it looks like I do not receive mail on olegsukhodolsky@netbeans.org (perhaps I need to do something to special for this). So, if you want show me the example with modal dialog and SwingWorker which doesn't work could you please attach it to this issue. Thanks, Oleg.
Hello Oleg, I found out that a modal dialog + SwingWorker does not work for my problem. As I said I have to block the EDT in order to prevent the netbeans platform from exiting. The only way I found to update a progress dialog while the EDT is blocked is via EventQueue.push/pop. This cannot be used because of the threading issues. So please tell me if you have another idea. I will try it. Best regards, Martin
Hi Martin, could you, please, be more specify why modal dialog + SwingWoker doesn't work? You can not exit while modal dialog is visible and EDT process your events, it is almost the same as push()/pop(). Thanks, Oleg.
Created attachment 41842 [details] Test case showing problem with SwingWorker
Hello Oleg, I just added an example (SwingWorkerProblem.java) showing my problem with SwingWorker. Best regards, Martin
Hi Martin, there are two problems in your test: 1. SimpleProgressDialog is not a modal dialog (by default dialog is modeless) add this line (or something similar) to its ctor super((JFrame)null, true); 2. you need to create Worker and execute it before showing the dialog (since show() for modal dialog is blocking. Thus your actionPerformed() should looks like: SimpleProgressDialog dialog = new SimpleProgressDialog(); dialog.pack(); Worker worker = new Worker(dialog); worker.execute(); dialog.setVisible(true); After these changes all works fine. BTW SwingWoker has setProgress() and done() methods which you can use instead of all invokeLater() (see http://download.java.net/jdk7/docs/api/javax/swing/SwingWorker.html for more information). Here is a possible Worker which will do what you want: private static final class Worker extends SwingWorker<Object, Void> implements PropertyChangeListener { private SimpleProgressDialog dialog; public Worker(SimpleProgressDialog dialog) { this.dialog = dialog; this.addPropertyChangeListener(this); } protected Object doInBackground() throws Exception { for (int i = 0; i < 10; i++) { Thread.sleep(500); setProgress(i+1); } return null; } protected void done() { dialog.setVisible(false); } public void propertyChange(PropertyChangeEvent evt) { if ("progress".equals(evt.getPropertyName())) { dialog.setProgress((Integer)evt.getNewValue()); } } } Note that after such changes you can remove DialogCloser and ProgressSetter as unused. Also there is no needs to call get() on the worker (unless you do really need its result). Hope this helps. Regards, Oleg.
Hello Oleg, thank you very much for your help. Your remarks indeed fixed my problem. Once again thank you and have a nice weekend. Best regards, Martin
Hi Martin, I'm happy to hear that one of your problems has been resolved. But this issue contains one more problem (with push() on startup) And it would be nice to figure out the cause of this problem. I've spent some time studying our code and found no problems which may be caused by push() (if it is the last call in runnable which is sent to EDT by invokeLater() or invokeAndWait()). So, I have to say that I'll be unable to help neither to you nor to NB to resolve it unless I will have some test which reproduce it. Thanks in advance, Oleg.
Hello, A few days ago we switched to netbeans 5.5.1 but this bug (java.lang.IllegalStateException: Assertion failed. WindowsAPI is required to be called from AWT thread only) initially reported for 5.5 is still present. I would like to know if there has been some progress in resolving this issue. We are very concerned about this bug because we have to release a new software based on the netbeans platform in a few months. Best regards, Martin
Hi Martin, as far as I remember for some problems you have we have found workaround. for another I've asked for the test to reproduce. Also as far as I understand the causes of the problems are either your code (which wants more than JDK provides) or some bugs in JDK which can not be resolved by update version of NetBeans :( Oleg.
See also the following related JDK bugs: http://bugs.sun.com/view_bug.do?bug_id=6424157 - "java.awt.EventQueue push/pop might cause threading issues" http://bugs.sun.com/view_bug.do?bug_id=6553239 - "one more threading problem with EventQueue.pop()"
Great mpetras, thanks for links. They are indeed related to this bug, test code pattern which is attached to 6424157 and 6553239 is very similar to our pattern in NonGui.java. Closing as wontfix, looking forward to 6424157 and 6553239 fixes, which will on 99% fix our problem here as well. Btw I added netbeans keyword to mentioned JDK bugs.
If you think that the problem should be fixed earlier than jdk7, I'd suggest to escalate it.
As the reporter of this bug I would appreciate it very much if this problem would be fixed earlier than jdk7. Best regards, Martin Goettlicher
Thanks Oleg. What am I supposed to do in order to escalate? Thanks for info in advance.
to dsimonek: I do not know the exact algorithm, but I hope your manager knows. If not please send my a mail and I will try to figure this out. Oleg.
*** Issue 123107 has been marked as a duplicate of this issue. ***
Now this bug seems to be resolved for Martin, but there is still another manifestation of this - performance tests fail because of this, see: http://beetle.czech.sun.com/automatedtests/xtest/netbeans_6.0/200711261600/qa-performance/spb-perf-sol/testrun_071127-212410/testbag_2/htmlresults/suites/TEST-gui.MeasureWebActions.html#gui.action.PasteInJspEditor.Paste%20in%20the%20JSP%20Editor (sorry for the Sun-internal link). See also issue 123107, which was just marked as a duplicate of this. Since we can not wait for the JDK fix, a workaround needs to be provided on the NetBeans side. Can a workaround be implemented either in NetBeans or in the test infrastructure? Thanks.
When running an application based on the netbeans platform (version 5.5.1) with assertions enabled, I get the following assertion about 4-5 times a week. The problem seems to be more frequent on multicore systems than on singlecore systems. Because I can't do anything against this assertion (except for switching them off which I don't want to do during development) I would like to reopen this bug. Since the platform startup code hasn't changed that much (especially pushing a new EventQueue is still present in the code which I think is the cause of the problem) between 5.5.1 and 6.1 I suspect that 6.1 is affected too. Best regards, Martin java.lang.AssertionError: WindowsAPI is required to be called from AWT thread only, see http://www.netbeans.org/download/dev/javadoc/OpenAPIs/org/openide/doc-files/threading.html at org.netbeans.core.windows.WindowManagerImpl.assertEventDispatchThread(WindowManagerImpl.java:1136) at org.netbeans.core.windows.WindowSystemImpl.load(WindowSystemImpl.java:43) at org.netbeans.core.NonGui$3.run(NonGui.java:224) at java.awt.event.InvocationEvent.dispatch(Unknown Source) [catch] at java.awt.EventQueue.dispatchEvent(Unknown Source) at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source) at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source) at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.awt.EventDispatchThread.run(Unknown Source)
to mgoe: This is bug in JDK, not in Netbeans, JDK bug is linked from here. I can do nothing with it, sorry. to pjiricka: No workaround exist at our side at the time, sorry. And I think no workaround is possible. I agree that this bug is important and nasty, but I can do nothing with it. IMHO we should escalate on JDK team if we have some always reproducible scenario - there is maximum technical info in this issue already which I can give.
*** Issue 133687 has been marked as a duplicate of this issue. ***
*** Issue 133698 has been marked as a duplicate of this issue. ***
*** Issue 133686 has been marked as a duplicate of this issue. ***
To dsimonek, please have a closer look at my posting from Tue Apr 15. Its not the "usual" but nevertheless annoying IllegalStateException. Its an AssertionError which terminates the program. I totally agree that this problem should be given a higher priority. If its not possible to fix the jdk soon (jdk bugs are from 2006) you could perhaps omit the use of EventQueue.push(). Best regards, Martin Goettlicher
Build: NetBeans IDE 6.1 (Build 200804211638) VM: Java HotSpot(TM) Client VM, 10.0-b19, Java(TM) SE Runtime Environment, 1.6.0_05-b13 OS: Windows XP, 5.1, x86 User Comments: ?????? ????????? ?????? ? ?? ????? ????.
Created attachment 60798 [details] stacktrace
Build: NetBeans IDE 6.0 (Build 200711261600) VM: Java HotSpot(TM) Client VM, 10.0-b19 OS: Windows XP, 5.1, x86 User Comments: I had just started up my copy of NetBeans IDE 6.0 after turning on the laptop a couple minutes earlier. Only other program running before hand was Pidgeon Portable 2.1.1
Created attachment 60823 [details] stacktrace
This issue has already 20 duplicates
*** Issue 134784 has been marked as a duplicate of this issue. ***
Created attachment 61503 [details] stacktrace
This issue has already 50 duplicates
Created attachment 61953 [details] stacktrace
This issue has already 50 duplicates see http://statistics.netbeans.org/exceptions/detail.do?id=11548
This issue has already 100 duplicates see http://statistics.netbeans.org/exceptions/detail.do?id=2435
Last bug is in org.netbeans.modules.visualgc.actions.ShowVisualGCAction
Last bug in org.netbeans.modules.visualgc.actions.ShowVisualGCAction isn't related to the original problem tracked by this issue (UI code really doesn't run in EDT), filed separate Issue 137987. Reassigning back to core/window system.
decreasing priority, not a stopper but JDK issue Tondo, could you escalate the JDK bug?
I consider it a stopper that we keep on popping up the error icon for it. Note that assertEventDispatchThread is a no-op in release builds, whereas assertEventDispatchThreadWeak will still be active in release builds.
-> dafe
improved logging - now it logs only on level FINE when assertions are disabled. I also tried to differentiate between NB and JDK problems and also changed method name so that exceptions reporter starts with new issues. http://hg.netbeans.org/core-main/rev/a31abe20eaad http://hg.netbeans.org/main/rev/a31abe20eaad
*** Issue 142802 has been marked as a duplicate of this issue. ***
It's a bit strange to see this issue marked RESOLVED/FIXED, while it is actually not fixed at all... At least from AWT side, which I present here instead of Oleg. This problem: java.lang.IllegalStateException: Assertion failed. WindowsAPI is required to be called from AWT thread only seems to be still present. Evaluation for #6424157 and a huge discussion here in the NB bug thread shows the source of the problem: when EventQueue is pushed/popped, it detaches its EventDispatchThread and a new EDT is created. I have inspected JDK code related to EventQueue.push/pop, and found it is very hard (impossible) to make a small and safe fix. Instead, I suggest the following solution, which also helps with other problems like #6542185, #4913324 and others. First, a new synchronization is introduced: a single lock is used instead of multiple monitors, one per each EventQueue. Second, when EventQueue.push/pop are called, the current EDT is reused by the next/previous queue. Third, all the exceptions on EDT are handled internally by AWT (with the exception of ThreadDeath), so EDT is not destroyed. No doubts, all the three items are backwards incompatible. However, JavaDoc specification for EventQueue class provides no information about synchronization and event dispatch thread lifecycle... That's why from the formal point of view the proposed changes don't break existing specification. Next, let's see if the fix is really helpful. I launched both Martin's tests (EventQueueFailure and EventQueueFailure2) and CheckThreadViolationRM exceptions are gone and no deadlocks are noticed. However, another problem appear: progress dialog is not painted correctly. This is easily understood: if we wait on EDT, no events are dispatched. Before the fix a new EDT was created and events were handled correctly. This problem can be solved by moving all the code with push(), pop() and dialog to a separate thread. The third test (SwingWorkerProblem) behavior is not changed: progress dialog is not repainted, which is correct as worker.get() is called on EDT. It would be fine to hear any ideas from NB team, if proposed solution is OK for them.
"when EventQueue.push/pop are called, the current EDT is reused by the next/previous queue" - refer to JRE bug #4786277 (and NB issue #28536) which I filed long ago which requested something like this. There was a nasty problem whereby the EDT was replaced during startup before any windows were visible, and we needed to push a queue which we would never pop just to make sure this would not happen. The reason had to do with the context class loader: we set it on the EDT in effect at the time, but later a new one was created with the original CCL. I cannot now find the code for this workaround so I don't know if it's still an issue for us. The original issue was rejected by the AWT team on the grounds that the CCL for the EDT is unspecified and that the behavior was not a bug (though looking at the code it was almost certainly unintentional).
*** Issue 149809 has been marked as a duplicate of this issue. ***
*** Issue 166026 has been marked as a duplicate of this issue. ***
*** Issue 166989 has been marked as a duplicate of this issue. ***
FYI. The fix for Java bug #4913324 (Deadlock when using two event queues): http://bugs.sun.com/view_bug.do?bug_id=4913324 has been recently pushed into OpenJDK workspace: http://hg.openjdk.java.net/jdk7/awt/jdk/rev/e6b46fc235b0 (will be integrated to the master JDK7 workspace in a couple of weeks). Any EventQueue.push/pop methods still fork a new EventDispatchThread - this behavior hasn't been changed - and therefore the assertion described in this bug #90590 is still triggered. However, we're now one step closer to the "ideal world" when a single EDT is shared between all the EventQueues - see my proposal above.