Community
Participate
Working Groups
This occurs intermittently on Eclipse 3.0 RC2. In the Java text editor, cut and copy sometimes don't work and at other times lock up the Eclipse GUI (need to kill Eclipse to continue). I have tested several scenarios and have seen the problem about half a dozen times (I only started using RC2 today) but I have been unable to figure out how to reliably reproduce the problem. (It may have something to do with the import block but I cannot be certain.) Sorry to be so vague.
is there anything in .log?
Are you sure the UI is locked up and not "just" the key board no longer working i.e. might it be the same problem as described in bug 67231? Can you try again and when you see the lock up go to the console and produce a stack dump using kill -QUIT or kill -3.
Yes, it is a true 'lock-up' (GUI not redrawn when another window is dragged over it). The good news is that a stack-trace gets logged. I ought to have looked for this yesterday: sorry and thanks for the prompt to do so :-) So, looking back through the log, the following happens every time but this is a fresh one (it took a matter of seconds this morning to generate it!): !SESSION Jun 16, 2004 01:50:32.774 --------------------------------------------- eclipse.buildId=I200406111814 java.version=1.4.2_02 java.vendor=Sun Microsystems Inc. BootLoader constants: OS=linux, ARCH=x86, WS=gtk, NL=en_US !ENTRY org.eclipse.ui 4 4 Jun 16, 2004 01:50:32.774 !MESSAGE Unhandled event loop exception !ENTRY org.eclipse.ui 4 0 Jun 16, 2004 01:50:32.776 !MESSAGE java.lang.NoClassDefFoundError !STACK 0 java.lang.NoClassDefFoundError at org.eclipse.jdt.core.dom.AST.newMethodDeclaration(AST.java:1503) at org.eclipse.jdt.core.dom.ASTConverter.convert(ASTConverter.java:697) at org.eclipse.jdt.core.dom.ASTConverter.buildBodyDeclarations (ASTConverter.java:336) at org.eclipse.jdt.core.dom.ASTConverter.convert(ASTConverter.java:274) at org.eclipse.jdt.core.dom.ASTConverter.convert(ASTConverter.java:152) at org.eclipse.jdt.core.dom.ASTParser.convert(ASTParser.java:711) at org.eclipse.jdt.core.dom.ASTParser.internalCreateAST (ASTParser.java:681) at org.eclipse.jdt.core.dom.ASTParser.createAST(ASTParser.java:574) at org.eclipse.jdt.internal.ui.javaeditor.ASTProvider.createAST (ASTProvider.java:439) at org.eclipse.jdt.internal.ui.javaeditor.ASTProvider.getAST (ASTProvider.java:391) at org.eclipse.jdt.internal.ui.javaeditor.ClipboardOperationAction.getClipboardData (ClipboardOperationAction.java:363) at org.eclipse.jdt.internal.ui.javaeditor.ClipboardOperationAction.doCutCopyWithImp ortsOperation(ClipboardOperationAction.java:300) at org.eclipse.jdt.internal.ui.javaeditor.ClipboardOperationAction.internalDoOperat ion(ClipboardOperationAction.java:256) at org.eclipse.jdt.internal.ui.javaeditor.ClipboardOperationAction$1.run (ClipboardOperationAction.java:225) at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:69) at org.eclipse.jdt.internal.ui.javaeditor.ClipboardOperationAction.run (ClipboardOperationAction.java:223) at org.eclipse.jface.action.Action.runWithEvent(Action.java:881) at org.eclipse.jface.action.ActionContributionItem.handleWidgetSelection (ActionContributionItem.java:915) at org.eclipse.jface.action.ActionContributionItem.access$2 (ActionContributionItem.java:866) at org.eclipse.jface.action.ActionContributionItem$7.handleEvent (ActionContributionItem.java:785) at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:82) at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:950) at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:2512) at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:2223) at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:1362) at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:1333) at org.eclipse.ui.internal.Workbench.createAndRunWorkbench (Workbench.java:252) at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:141) at org.eclipse.ui.internal.ide.IDEApplication.run (IDEApplication.java:96) at org.eclipse.core.internal.runtime.PlatformActivator$1.run (PlatformActivator.java:334) at org.eclipse.core.runtime.adaptor.EclipseStarter.run (EclipseStarter.java:272) at org.eclipse.core.runtime.adaptor.EclipseStarter.run (EclipseStarter.java:128) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.eclipse.core.launcher.Main.basicRun(Main.java:185) at org.eclipse.core.launcher.Main.run(Main.java:638) at org.eclipse.core.launcher.Main.main(Main.java:622)
If it is a deadlock we need the stack dump. The log only contains stack traces for errors. Moving to JCore to comment on the exception
On what looks like a related symptom, I usually get the following on startup: java.lang.ExceptionInInitializerError at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Unknown Source) at org.eclipse.jdt.core.dom.TryStatement.<clinit>(TryStatement.java:42) at org.eclipse.jdt.core.dom.AST.newTryStatement(AST.java:1960) at org.eclipse.jdt.core.dom.ASTConverter.convert(ASTConverter.java:2114) at org.eclipse.jdt.core.dom.ASTConverter.convert(ASTConverter.java:1855) at org.eclipse.jdt.core.dom.ASTConverter.convert(ASTConverter.java:1910) at org.eclipse.jdt.core.dom.ASTConverter.checkAndAddMultipleFieldDeclaration (ASTConverter.java:353) at org.eclipse.jdt.core.dom.ASTConverter.buildBodyDeclarations (ASTConverter.java:330) at org.eclipse.jdt.core.dom.ASTConverter.convert(ASTConverter.java:274) at org.eclipse.jdt.core.dom.ASTConverter.convert(ASTConverter.java:152) at org.eclipse.jdt.core.dom.AST.convertCompilationUnit(AST.java:253) at org.eclipse.jdt.internal.core.ReconcileWorkingCopyOperation.executeOperation (ReconcileWorkingCopyOperation.java:81) at org.eclipse.jdt.internal.core.JavaModelOperation.run (JavaModelOperation.java:700) at org.eclipse.jdt.internal.core.JavaModelOperation.runOperation (JavaModelOperation.java:739) at org.eclipse.jdt.internal.core.CompilationUnit.reconcile (CompilationUnit.java:1098) at org.eclipse.jdt.internal.ui.text.java.JavaReconcilingStrategy.reconcile (JavaReconcilingStrategy.java:88) at org.eclipse.jdt.internal.ui.text.java.JavaReconcilingStrategy.initialReconcile (JavaReconcilingStrategy.java:156) at org.eclipse.jdt.internal.ui.text.CompositeReconcilingStrategy.initialReconcile (CompositeReconcilingStrategy.java:114) at org.eclipse.jdt.internal.ui.text.JavaCompositeReconcilingStrategy.initialReconci le(JavaCompositeReconcilingStrategy.java:122) at org.eclipse.jface.text.reconciler.MonoReconciler.initialProcess (MonoReconciler.java:104) at org.eclipse.jdt.internal.ui.text.JavaReconciler.initialProcess (JavaReconciler.java:304) at org.eclipse.jface.text.reconciler.AbstractReconciler$BackgroundThread.run (AbstractReconciler.java:169) Caused by: java.lang.RuntimeException: Structural property descriptor has wrong node class! at org.eclipse.jdt.core.dom.ASTNode.addProperty(ASTNode.java:1731) at org.eclipse.jdt.core.dom.CatchClause.<clinit>(CatchClause.java:51) ... 23 more java.lang.NoClassDefFoundError at org.eclipse.jdt.core.dom.AST.newTryStatement(AST.java:1960) at org.eclipse.jdt.core.dom.ASTConverter.convert(ASTConverter.java:2114) at org.eclipse.jdt.core.dom.ASTConverter.convert(ASTConverter.java:1855) at org.eclipse.jdt.core.dom.ASTConverter.convert(ASTConverter.java:770) at org.eclipse.jdt.core.dom.ASTConverter.buildBodyDeclarations (ASTConverter.java:336) at org.eclipse.jdt.core.dom.ASTConverter.convert(ASTConverter.java:274) at org.eclipse.jdt.core.dom.ASTConverter.convert(ASTConverter.java:152) at org.eclipse.jdt.core.dom.AST.convertCompilationUnit(AST.java:253) at org.eclipse.jdt.internal.core.ReconcileWorkingCopyOperation.executeOperation (ReconcileWorkingCopyOperation.java:81) at org.eclipse.jdt.internal.core.JavaModelOperation.run (JavaModelOperation.java:700) at org.eclipse.jdt.internal.core.JavaModelOperation.runOperation (JavaModelOperation.java:739) at org.eclipse.jdt.internal.core.CompilationUnit.reconcile (CompilationUnit.java:1098) at org.eclipse.jdt.internal.ui.text.java.JavaReconcilingStrategy.reconcile (JavaReconcilingStrategy.java:88) at org.eclipse.jdt.internal.ui.text.java.JavaReconcilingStrategy.initialReconcile (JavaReconcilingStrategy.java:156) at org.eclipse.jdt.internal.ui.text.CompositeReconcilingStrategy.initialReconcile (CompositeReconcilingStrategy.java:114) at org.eclipse.jdt.internal.ui.text.JavaCompositeReconcilingStrategy.initialReconci le(JavaCompositeReconcilingStrategy.java:122) at org.eclipse.jface.text.reconciler.MonoReconciler.initialProcess (MonoReconciler.java:104) at org.eclipse.jdt.internal.ui.text.JavaReconciler.initialProcess (JavaReconciler.java:304) at org.eclipse.jface.text.reconciler.AbstractReconciler$BackgroundThread.run (AbstractReconciler.java:169)
Looks like VM or classloader issues. There are classes not found, or exception during invocation of <clinit> which shouldn't occur at all. Moving to platform as may be classloader related.
If a deadlock on classload was happening then it would have been broken by the timeout mechanism we have and a message would be in the log. NoClassDefFoundErrors are however strange. Are you seeing this message when selfhosting? If yes, do you have jdt loaded in your workspace? Otherwise I have seen NoClassDefFoundError in JDT but this only happens on shutdown because the indexer is not killed properly. However here it does not seems to be the case. Jeff, the next time it happens please provide us with a full stack.
Hi, I have never waited long enough to see a time-out mechanism kick-in. I don't know what you mean by "self-hosting" but I do have JDT loaded...I'm developing a plug-in. I confess that I really don't know how to get a full stack. I have a BASH script that enables me to set the memory size and I can select the Terminal button when I run the script. I kill locked-up instances of Eclipse using System Monitor. (Off subject: Although I've been developing software commercially for more than twenty years and developing Java software for five years, it's only recently that I switched from Windows to Linux, just as an experiment really (about six months ago). Personally, I find Linux uses much more memory than Windows and is slower than Windows but I like the software (no leaked files locks and lots of nice little features) so I don't intend to stop any time soon.) If you let me know how to generate a full stack, I'll do it :-) Warmest regards, Jeff
The time out occurs after 5 seconds so you should have seen it. To get the full dump please see Daniel's comment #2. Which eclipse is blocking? The one in which you develop, or the one you start from within eclipse?
The Eclipse I use for development has the problem, i.e. not the Run-time Workbench. I figured out that I need to do a ps -efH to see the PID then a kill -Q PID so, with Daniel's help, I think I now know how to get a full dump. Unfortunately, since I've added more text to the file that caused the problem, I no longer see the problem (or, it's harder to recreate, I suspect). I'll try to recreate the problem. I'm surprized that other people haven't reported it (perhaps they saw this report and took it no futher). Please remember, however, that the stack trace did arise from a cut/copy operation, notice: org.eclipse.jdt.internal.ui.javaeditor.ClipboardOperationAction.run (ClipboardOperationAction.java:223) so the stack trace ought to get you to the right ballpark (AST.java:1503).
I was lucky enough to get this or very similar deadlock when running eclipse under debugger. Unfortunately "Threads and Monitors" view did not provide too much information so here is a thread stack snapshot (as by "Copy Stack" from debug view). I am running Win2k SP2, Sun JDK 1.4.2_04, Eclipse 200406111814 with cheetah(!) from CVS. Hope this helps. System Thread [Finalizer] (Suspended) Object.wait(long) line: not available [native method] System Thread [Reference Handler] (Suspended) Object.wait(long) line: not available [native method] Thread [main] (Suspended) Object.wait(long) line: not available [native method] Object.wait() line: 429 ASTProvider.getAST(IJavaElement, boolean, IProgressMonitor) line: 373 ClipboardOperationAction.getClipboardData(IJavaElement, int, int) line: 363 ClipboardOperationAction.doCutCopyWithImportsOperation() line: 300 ClipboardOperationAction.internalDoOperation() line: 256 ClipboardOperationAction$1.run() line: 225 BusyIndicator.showWhile(Display, Runnable) line: 69 ClipboardOperationAction.run() line: 223 ClipboardOperationAction(Action).runWithEvent(Event) line: 881 ActionHandler.execute(Map) line: 141 Command.execute(Map) line: 132 WorkbenchKeyboard.executeCommand(String) line: 469 WorkbenchKeyboard.press(List, Event) line: 887 WorkbenchKeyboard.processKeyEvent(List, Event) line: 928 WorkbenchKeyboard.filterKeySequenceBindings(Event) line: 546 WorkbenchKeyboard.access$2(WorkbenchKeyboard, Event) line: 494 WorkbenchKeyboard$1.handleEvent(Event) line: 259 EventTable.sendEvent(Event) line: 82 Display.filterEvent(Event) line: 714 StyledText(Widget).sendEvent(Event) line: 795 StyledText(Widget).sendEvent(int, Event, boolean) line: 820 StyledText(Widget).sendEvent(int, Event) line: 805 StyledText(Control).sendKeyEvent(int, int, int, int, Event) line: 1729 StyledText(Control).sendKeyEvent(int, int, int, int) line: 1725 StyledText(Control).WM_CHAR(int, int) line: 3053 StyledText(Control).windowProc(int, int, int, int) line: 2956 Display.windowProc(int, int, int, int) line: 3298 OS.DispatchMessageW(MSG) line: not available [native method] OS.DispatchMessage(MSG) line: 1460 Display.readAndDispatch() line: 2396 Workbench.runEventLoop(Window$IExceptionHandler, Display) line: 1362 Workbench.runUI() line: 1333 Workbench.createAndRunWorkbench(Display, WorkbenchAdvisor) line: 252 PlatformUI.createAndRunWorkbench(Display, WorkbenchAdvisor) line: 141 IDEApplication.run(Object) line: 96 PlatformActivator$1.run(Object) line: 334 EclipseStarter.run(Object) line: 272 EclipseStarter.run(String[], Runnable) line: 128 NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method] NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39 DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25 Method.invoke(Object, Object[]) line: 324 Main.basicRun(String[]) line: 185 Main.run(String[]) line: 638 Main.main(String[]) line: 622 System Thread [Signal Dispatcher] (Suspended) Thread [Framework Event Dispatcher] (Suspended) Object.wait(long) line: not available [native method] EventThread(Object).wait() line: 429 [local variables unavailable] EventThread.getNextEvent() line: 162 EventThread.run() line: 100 Thread [OSGi Console] (Suspended) Object.wait(long) line: not available [native method] FrameworkConsole.console() line: 264 FrameworkConsole.console(String[]) line: 236 FrameworkConsole.run() line: 207 Thread.run() line: 534 [local variables unavailable] Thread [Start Level Event Dispatcher] (Suspended) Object.wait(long) line: not available [native method] EventThread(Object).wait() line: 429 [local variables unavailable] EventThread.getNextEvent() line: 162 EventThread.run() line: 100 Thread [Reference Cleaner - 1] (Suspended) Object.wait(long) line: not available [native method] ReferenceQueue.remove(long) line: 111 ReferenceQueue.remove() line: 127 [local variables unavailable] ActionContributionItem$ImageCache$ReferenceCleanerThread.run() line: 207 Thread [Reference Cleaner - 2] (Suspended) Object.wait(long) line: not available [native method] ReferenceQueue.remove(long) line: 111 ReferenceQueue.remove() line: 127 [local variables unavailable] ActionContributionItem$ImageCache$ReferenceCleanerThread.run() line: 207 Thread [Java indexing] (Suspended) Object.wait(long) line: not available [native method] IndexManager(Object).wait() line: 429 [local variables unavailable] IndexManager(JobManager).run() line: 338 Thread.run() line: 534 [local variables unavailable] Thread [Worker-8] (Suspended) Object.wait(long) line: not available [native method] WorkerPool.sleep(long) line: 166 WorkerPool.startJob(Worker) line: 193 Worker.run() line: 59
Philippe what does the getAST wait for / on?
Just in case you anyone is interested, I spent some more time on this and here is what I've found. The problem is triggered by a runtime exception during execution of org.eclipse.jdt.internal.ui.javaeditor.ASTProvider#getAST. I changed the source to always throw NullPointerException to reproduce it 100% ;-). Assuming that you have similar change here are the steps to reproduce the deadlock First, double check that you can reproduce a runtime exception 1. Open a file in java editor 2. Select some text 3. Ctrl-C. At this point you should get popup window with information about the runtime exception. Now the deadlock 4. Edit the file but do not save 5. Select some text 6. Ctrl-C. At this point eclipse locks up and you'll have to kill it. Hope this provides enough information to debug this problem, but should you need any additional details I'll be happy to help (btw, my ibm email is igorf at ca ibm com).
Re: comment#12. The DOM AST doesn't wait on anything. It just never gets created due to suspicious exception in runtime. This is why I forwarded it to you. However, as Igor stated, this is only one of the problems. It appears that if an exception occurs in this very code (like it does here), it then causes some deadlock above JDT Core (likely in UI components). A thread dump would definitely help to figure out what is the deadlock situation. CC'ing Dirk who owns the call to the DOM AST creation code.
CC'ing Kai as well since the call comes from ASTProvider
Suspect something in Text land...
Where exactly did you modifiy the code to throw an NPE? Note: the call to ICompilationUnit.reconcile(...) is already protected with a finally block in which we send out the notification.
Sorry for confusion, it was not ASTProvider#getAST, but ASTConverter#convert. Here is the diff that I double and tripple check to "work" with the steps. Index: dom/org/eclipse/jdt/core/dom/ASTConverter.java =================================================================== RCS file: /home/eclipse/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTConverter.java,v retrieving revision 1.154 diff -u -r1.154 ASTConverter.java --- dom/org/eclipse/jdt/core/dom/ASTConverter.java 9 Jun 2004 18:17:46 -0000 1.154 +++ dom/org/eclipse/jdt/core/dom/ASTConverter.java 18 Jun 2004 19:56:38 -0000 @@ -247,6 +247,7 @@ public TypeDeclaration convert(org.eclipse.jdt.internal.compiler.ast.TypeDeclaration typeDeclaration) { checkCanceled(); + Object o = null; o.toString(); TypeDeclaration typeDecl = this.ast.newTypeDeclaration(); int modifiers = typeDeclaration.modifiers; modifiers &= ~IConstants.AccInterface; // remove AccInterface flags
will investigate
Even with the added NPE I could not reproduce the deadlock. What I see is: - the finally block which wakes up waiting callers gets called - I get a dialog "Error Running Operations" which comes back all the time but the UI is not blocked: I can move the focus away from the editor e.g. to the Outline view and then close the editor. Also, I (and others) haven't seen this without the modified code. What's really important is to get the "real" exception that causes this. Setting resolution to REMIND until we have further data to investigate.
I spent some time on this yesterday, and here is what I've found. My workspace has one java source opened. I start eclipse with the added NPE under debugger and here is what I see 1. Background java reconciliation thread dies because of the NPE and does not get restarted. 2. If I copy from clean (i.e. unchanged) aditor, ASTProvider#getAST invokes ASTProvider#createAST which eventually hits my planted NPE and I get "Error Running Operations" dialog. Nothing gets copied to the clipboard. 3. ASTProvider#aboutToBeReconciled is invoked when I modifty the source in the editor. The source is considered "being reconsiled" stay in this state forever since there is no reconcilation thread running. 4. If I now copy from this dirty editor, ASTProvider#getAST will determine that the source is being reconsiled (by calling ASTProvider#isReconciling) and will wait forever for reconsiliation to finish. This blocks event delivery thread and as a result Eclise UI stops funtioning. I would consider few improvements to make eclipse more robust First, it looks like a "generally good idea" to restart background reconciliation threads. Second, make synchronization between UI and background reconciliation threads more robust. For example, instead of waiting forever, UI could wait with timeout and have a fallback behaviour should timeout ever occure. And last, how come single "bad" plugin can block entire elcipse UI? It looks so much like Windows 3.1. ;-) Anyways, I agree with Daniel that it is more important to understand the cause of real exception.
I would say there are 2 problems. 1. Exception should not occur, and we want to understand it. 2. An exception should not kill the IDE. It should be robust enough to do something reasonable.
I can partially confirm your analysis: we do not restart the reconcile thread, however, what should happen (and what I see using JRE 1.4.2_03) is that the finally block in JavaReconcilingStrategy resets the AST provider and since the reconcile thread is already shutting down no further aboutToBeReconciled will be sent. What VM do you use? 1.5 maybe? We could make the code more robust with a time-out but this time-out must be computed in function of the CU size because otherwise we would always compute two AST for large CUs (one during reconcile and one after the time-out. Instead of computing the AST after the time-out we could add API to check whether the reconcile thread is alive and if so, continue to wait. Philippe can you provide some basic timing information for the reconcile operation especially in function of file size (e.g. is it linear)?
As I mentioned earlier, I am using SUN JDK 1.4.2_04. Java reconciliation thread dies during eclipse startup. To make it clear, I have never seen this problem with regular JDT. It happens a lot with cheetah (due to unimplemented features) and with JDT I had to plant artificial NPE to reproduce it. Also, I don't think UI wait timeout should NOT be a function of CU size, but should be set based on user UI response expectations. If reconciliation finishes within this time, great, use reconciled AST to copy source to the clipboard. If, however, reconciliation does not finish within timeout period, then copy plain text to the clipboard. This way UI will become more responsive for very large CUs and as a good side effect it will tolerate problems with background reconciliation.
I can now reproduce it with the steps outline in comment 13. I could first not reproduce it because the "Update imports on paste" was disabled in my test workspace. J Core will (or has already) put in code into the Cheeta branch which will no longer break the reconcile. Regarding your second section in comment 24: we chache the AST for the active editor and use this editor's AST for several features one of which is the smart copy/past of imports. If we followed your strategy to not have an AST if it could not be computed after a fixed time-out then features like semantic coloring, override indication in vertical ruler, occurrence marking, etc. would be disabled (especially for large CUs).
Created attachment 12565 [details] Patch against AbstractReconciler which prevents calls to aboutToBeReconciled() in cases where the reconcile thread is no longer alive
The fix is about improving the robustness of the reconciler framework. As pointed out, it is not required for the Java tooling any longer. In case Thread.isAlive is not 100% reliable method, there is still room to fail, however not as badly as right now.
Approved to be released into RC4
Build I200406221600.
Verified in I20040625 I loaded jdt.core in workspace, applied patch #18 and followed steps in #13. I got the exception (as expected), but could not lock up eclipse.