This Bugzilla instance is deprecated, and most Eclipse projects now use GitHub or Eclipse GitLab. Please see the deprecation plan for details.
Bug 426485 - [EditorMgmt][Split editor] Each split causes editors to be leaked
Summary: [EditorMgmt][Split editor] Each split causes editors to be leaked
Status: VERIFIED FIXED
Alias: None
Product: Platform
Classification: Eclipse Project
Component: UI (show other bugs)
Version: 4.4   Edit
Hardware: All All
: P3 critical (vote)
Target Milestone: 4.4 RC3   Edit
Assignee: Eric Moffatt CLA
QA Contact: Eric Moffatt CLA
URL:
Whiteboard:
Keywords: performance
Depends on:
Blocks:
 
Reported: 2014-01-23 11:55 EST by Szymon Ptaszkiewicz CLA
Modified: 2018-03-09 11:20 EST (History)
3 users (show)

See Also:
daniel_megert: review+
pwebster: review+


Attachments
Error Log to check the time stamp of the exception (34.06 KB, image/png)
2014-05-26 04:28 EDT, Martin Mathew CLA
no flags Details
Picture with the unexpected refrences (48.40 KB, image/png)
2014-05-28 03:36 EDT, Dani Megert CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Szymon Ptaszkiewicz CLA 2014-01-23 11:55:50 EST
Build id: I20140122-2000

After I reproduced bug 426477 and then closed all editors I started receiving NPEs like the one below every 5 minutes without any user interaction. Seems like some periodic task is executed every 5 minutes even if Eclipse is unused and no editors are opened.

java.lang.NullPointerException
	at org.eclipse.ui.texteditor.AbstractTextEditor.saveState(AbstractTextEditor.java:7080)
	at org.eclipse.ui.internal.EditorReference.getEditorState(EditorReference.java:177)
	at org.eclipse.ui.internal.EditorReference.persist(EditorReference.java:99)
	at org.eclipse.ui.internal.Workbench$15.run(Workbench.java:1146)
	at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
	at org.eclipse.ui.internal.Workbench.persist(Workbench.java:1135)
	at org.eclipse.ui.internal.Workbench.access$44(Workbench.java:1133)
	at org.eclipse.ui.internal.Workbench$60.runInUIThread(Workbench.java:2760)
	at org.eclipse.ui.progress.UIJob$1.run(UIJob.java:95)
	at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35)
	at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:136)
	at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:4147)
	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3764)
	at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$9.run(PartRenderingEngine.java:1122)
	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
	at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1006)
	at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:146)
	at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:612)
	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
	at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:565)
	at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:150)
	at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:125)
	at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:109)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:80)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:372)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:226)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:60)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
	at java.lang.reflect.Method.invoke(Method.java:611)
	at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:636)
	at org.eclipse.equinox.launcher.Main.basicRun(Main.java:591)
	at org.eclipse.equinox.launcher.Main.run(Main.java:1450)
Comment 1 Szymon Ptaszkiewicz CLA 2014-01-23 12:05:41 EST
And I keep getting such errors every 5 minutes.
Comment 2 Szymon Ptaszkiewicz CLA 2014-01-23 12:24:28 EST
When I finally decided to restart my Eclipse to get rid of the annoying periodic popup dialog I received one more NPE:

java.lang.NullPointerException
	at org.eclipse.ui.texteditor.AbstractTextEditor.saveState(AbstractTextEditor.java:7080)
	at org.eclipse.ui.internal.EditorReference.getEditorState(EditorReference.java:177)
	at org.eclipse.ui.internal.EditorReference.persist(EditorReference.java:99)
	at org.eclipse.ui.internal.Workbench$15.run(Workbench.java:1146)
	at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
	at org.eclipse.ui.internal.Workbench.persist(Workbench.java:1135)
	at org.eclipse.ui.internal.Workbench.busyClose(Workbench.java:1078)
	at org.eclipse.ui.internal.Workbench.access$19(Workbench.java:1029)
	at org.eclipse.ui.internal.Workbench$19.run(Workbench.java:1332)
	at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:70)
	at org.eclipse.ui.internal.Workbench.close(Workbench.java:1330)
	at org.eclipse.ui.internal.Workbench.restart(Workbench.java:2508)
	at org.eclipse.ui.internal.handlers.RestartWorkbenchHandler.execute(RestartWorkbenchHandler.java:31)
	at org.eclipse.ui.internal.handlers.HandlerProxy.execute(HandlerProxy.java:290)
	at org.eclipse.ui.internal.handlers.E4HandlerProxy.execute(E4HandlerProxy.java:90)
	at sun.reflect.GeneratedMethodAccessor36.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
	at java.lang.reflect.Method.invoke(Method.java:611)
	at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:56)
	at org.eclipse.e4.core.internal.di.InjectorImpl.invokeUsingClass(InjectorImpl.java:243)
	at org.eclipse.e4.core.internal.di.InjectorImpl.invoke(InjectorImpl.java:224)
	at org.eclipse.e4.core.contexts.ContextInjectionFactory.invoke(ContextInjectionFactory.java:132)
	at org.eclipse.e4.core.commands.internal.HandlerServiceHandler.execute(HandlerServiceHandler.java:163)
	at org.eclipse.core.commands.Command.executeWithChecks(Command.java:499)
	at org.eclipse.core.commands.ParameterizedCommand.executeWithChecks(ParameterizedCommand.java:508)
	at org.eclipse.e4.core.commands.internal.HandlerServiceImpl.executeHandler(HandlerServiceImpl.java:222)
	at org.eclipse.e4.ui.workbench.renderers.swt.HandledContributionItem.executeItem(HandledContributionItem.java:776)
	at org.eclipse.e4.ui.workbench.renderers.swt.HandledContributionItem.handleWidgetSelection(HandledContributionItem.java:668)
	at org.eclipse.e4.ui.workbench.renderers.swt.HandledContributionItem.access$6(HandledContributionItem.java:652)
	at org.eclipse.e4.ui.workbench.renderers.swt.HandledContributionItem$4.handleEvent(HandledContributionItem.java:584)
	at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
	at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4353)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1061)
	at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:4172)
	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3761)
	at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$9.run(PartRenderingEngine.java:1122)
	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
	at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1006)
	at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:146)
	at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:612)
	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
	at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:565)
	at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:150)
	at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:125)
	at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:109)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:80)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:372)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:226)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:60)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
	at java.lang.reflect.Method.invoke(Method.java:611)
	at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:636)
	at org.eclipse.equinox.launcher.Main.basicRun(Main.java:591)
	at org.eclipse.equinox.launcher.Main.run(Main.java:1450)
Comment 3 Dani Megert CLA 2014-01-28 05:42:50 EST
Szymon I cannot reproduce this. Can you provide steps?
Comment 4 Szymon Ptaszkiewicz CLA 2014-01-28 06:19:58 EST
(In reply to Dani Megert from comment #3)
> Szymon I cannot reproduce this. Can you provide steps?

Unfortunately not. It happened just once I don't know what caused this. I guess that for some reason the UI model was in a bad state because it looks like it kept a reference to an editor after all editors were closed and when running periodic workbench save it tried to persist this editor. Restarting Eclipse solved the problem so it's not a big problem.

I'm fine with closing this bug as WORKSFORME, but I it's just worth to know that such NPEs happened (at least on my machine).
Comment 5 Dani Megert CLA 2014-01-28 06:23:39 EST
(In reply to Szymon Ptaszkiewicz from comment #4)
> I'm fine with closing this bug as WORKSFORME, but I it's just worth to know
> that such NPEs happened (at least on my machine).

Right. I think we're closing this for now. As you pointed out, the problem would most likely be in the UI model and not in Text.
Comment 6 Martin Mathew CLA 2014-05-26 04:28:16 EDT
Created attachment 243474 [details]
Error Log to check the time stamp of the exception

Issue was reproducible in 4.4 RC2 Build id: I20140522-1330

Steps to reproduce:
Follow the steps in bug 435740 which results in IAE. 
Just wait, every 5 minutes after the IAE is thrown the NPE was consistently thrown:
java.lang.NullPointerException
	at org.eclipse.ui.texteditor.AbstractTextEditor.saveState(AbstractTextEditor.java:7082)
	at org.eclipse.ui.internal.EditorReference.getEditorState(EditorReference.java:177)
	at org.eclipse.ui.internal.EditorReference.persist(EditorReference.java:99)
	at org.eclipse.ui.internal.Workbench$15.run(Workbench.java:1201)
	at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
	at org.eclipse.ui.internal.Workbench.persist(Workbench.java:1189)
	at org.eclipse.ui.internal.Workbench.access$46(Workbench.java:1187)
	at org.eclipse.ui.internal.Workbench$61.runInUIThread(Workbench.java:2951)
	at org.eclipse.ui.progress.UIJob$1.run(UIJob.java:97)
	at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35)
	at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:136)
	at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:4147)
	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3764)
	at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$9.run(PartRenderingEngine.java:1152)
	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
	at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1033)
	at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:148)
	at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:636)
	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
	at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:579)
	at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:150)
	at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:135)
	at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:379)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:233)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:483)
	at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:648)
	at org.eclipse.equinox.launcher.Main.basicRun(Main.java:603)
	at org.eclipse.equinox.launcher.Main.run(Main.java:1465)
Comment 7 Martin Mathew CLA 2014-05-26 04:30:36 EDT
It could be related to bug 435740.
Comment 8 Dani Megert CLA 2014-05-26 09:54:57 EDT
(In reply to Manju Mathew from comment #7)
> It could be related to bug 435740.

This just makes a big leak visible: each time an editor is split (vertically or horizontally), a new editor instance is created. However, once that editor is closed it will only dispose two editors if still split or one editor if no longer in split state.

Those "dead" editors will be updated in the background e.g. when persisting the state every 5 minutes.

If the perspective is then closed, lots of errors will happen, like e.g. the reported NPE for each "dead" editor every 5 minutes.
Comment 9 Eric Moffatt CLA 2014-05-26 15:14:38 EDT
Yoiks ! It does appear that unsplitting doesn't tear down the 'cloned' editor...I'm on it !
Comment 10 Eric Moffatt CLA 2014-05-26 15:21:20 EDT
OK, I now understand this one...I wasn't explicitly setting the 'cloned' editor's TBR to false while it was still connected to the model. By the time it becomes unrendered through the removal the code can't find its way back to the relevant workbench window so we don't remeve the reference...

I have a patch ready for this but I'm experiencing some Gerrit related issues right now (not related to Luna...;-).

If I don't get the patch in today it'll be there early tomorrow once Paul straightens me out.
Comment 11 Eric Moffatt CLA 2014-05-27 09:15:12 EDT
Here's the patch that sets the TBR of the clone to false before removing it...

  https://git.eclipse.org/r/27369
Comment 12 Paul Webster CLA 2014-05-27 16:16:21 EDT
(In reply to Eric Moffatt from comment #10)
> OK, I now understand this one...I wasn't explicitly setting the 'cloned'
> editor's TBR to false while it was still connected to the model. By the time
> it becomes unrendered through the removal the code can't find its way back
> to the relevant workbench window so we don't remeve the reference...

The patch looks straight forward.  I have a question.  This doesn't apply to a split editor that's  still split and then the entire editor is closed, right?  They were always being cleaned up?  It's just an editor that was split/unsplit that was leaking?

PW
Comment 13 Dani Megert CLA 2014-05-28 03:33:25 EDT
(In reply to Paul Webster from comment #12)
> The patch looks straight forward.  I have a question.  This doesn't apply to
> a split editor that's  still split and then the entire editor is closed,
> right?  They were always being cleaned up?  It's just an editor that was
> split/unsplit that was leaking?

Almost. Currently, each split creates a new editor. Closing unsplit disposes one editor and closing in split state disposes two. Any further splitting creates another leak.
Comment 14 Dani Megert CLA 2014-05-28 03:35:27 EDT
I spent some more time this morning to fully test & debug the NPE scenario (comment 0) and found out, that the fix does not clean up the editor references. It does call dipsose() with the patch though.

Test Case:
1. Go to org.eclipse.ui.internal.Workbench.persist(boolean)
2. Set a breakpoint after init of 'editorReferences'
3. Reduce Workbench.getAutoSaveJobTime() to something smaller, otherwise you 
   have to wait minutes
4. Start the target workbench, add a project and a new file
5. Split and unsplit the file
6. close the file
7. wait for the breakpoint to be hit
==> 'editorReferences' will contain one reference but shouldn't (normal open/close does not leave a reference)

NOTE: if you split/unsplit many times it will contain many entries of the same editor reference (see attached picture).
Comment 15 Dani Megert CLA 2014-05-28 03:36:00 EDT
Created attachment 243604 [details]
Picture with the unexpected refrences
Comment 16 Eric Moffatt CLA 2014-05-28 11:23:37 EDT
Dani, I've amended the original commit to prevent adding a reference if it already is in the list. I missed this the first time because I was focused on 'removes' rather than 'adds'...;-(.

My testing for this one is a but different from yours. I opened an editor and did a lot of splitting, unsplitting, changing split orientations...finally I split the editor and closed it.

Then I added a BP at 'openEditor', opened a new editor and inspected the 'editorReferences' which was empty (as expected).
Comment 17 Eric Moffatt CLA 2014-05-28 13:31:40 EDT
Dani, I saw your comment about null checking 'clonedEditor'. This is unnecessary because the 'findElements' call *cannot* return nulls. If there are 3 values in the returned list they'll all be non-null (actually instances of MPart).

I think we should go with the current patch...
Comment 18 Paul Webster CLA 2014-05-28 14:24:41 EDT
+1 component lead

PW
Comment 19 Dani Megert CLA 2014-05-28 15:03:27 EDT
(In reply to Eric Moffatt from comment #17)
> Dani, I saw your comment about null checking 'clonedEditor'. This is
> unnecessary because the 'findElements' call *cannot* return nulls. If there
> are 3 values in the returned list they'll all be non-null (actually
> instances of MPart).
> 
> I think we should go with the current patch...

Makes sense.

We need a third reviewer.
Comment 21 Dani Megert CLA 2014-05-29 05:36:17 EDT
Verified in I20140528-2000.
Comment 22 David M. Karr CLA 2015-04-09 12:09:55 EDT
I have a question about this bug/fix.

Would this fix have already been integrated into 4.4.2 (or STS 3.6.4)?  That's what I have, and today I saw the following stacktrace:

!ENTRY org.eclipse.ui.workbench 4 2 2015-04-09 08:58:02.997
!MESSAGE Problems occurred when invoking code from plug-in: "org.eclipse.ui.workbench".
!STACK 0
java.lang.NullPointerException
	at org.eclipse.ui.texteditor.AbstractTextEditor.saveState(AbstractTextEditor.java:7083)
	at org.eclipse.ui.internal.EditorReference.getEditorState(EditorReference.java:177)
	at org.eclipse.ui.internal.EditorReference.persist(EditorReference.java:99)
	at org.eclipse.ui.internal.Workbench$15.run(Workbench.java:1201)
	at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
	at org.eclipse.ui.internal.Workbench.persist(Workbench.java:1189)
	at org.eclipse.ui.internal.Workbench.access$47(Workbench.java:1187)
	at org.eclipse.ui.internal.Workbench$61.runInUIThread(Workbench.java:2957)
	at org.eclipse.ui.progress.UIJob$1.run(UIJob.java:97)
	at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35)
	at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:136)
	at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:4147)
	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3764)
	at org.eclipse.jface.window.Window.runEventLoop(Window.java:832)
	at org.eclipse.jface.window.Window.open(Window.java:808)
	at org.eclipse.ui.internal.dialogs.WorkbenchPreferenceDialog.open(WorkbenchPreferenceDialog.java:221)
        ...
Comment 23 Dani Megert CLA 2015-04-10 04:14:39 EDT
(In reply to David M. Karr from comment #22)
> I have a question about this bug/fix.
> 
> Would this fix have already been integrated into 4.4.2 (or STS 3.6.4)? 

I don't know STS, but Eclipse has the fix since 4.4.

If you can reproduce the bug using 4.5 M6, then please file a new bug with steps to reproduce the NPE. Thanks.
Comment 24 David M. Karr CLA 2015-10-14 16:59:01 EDT
I don't know how to repeat this, but I just started seeing this in my Mars.1 instance (4.5.1).  I haven't restarted it yet.
Comment 25 Dani Megert CLA 2015-10-22 05:53:32 EDT
(In reply to David M. Karr from comment #24)
> I don't know how to repeat this, but I just started seeing this in my Mars.1
> instance (4.5.1).  I haven't restarted it yet.

If you see this with Mars.1 then please file a new bug with steps to reproduce the problem and cc me. Thanks.
Comment 26 David M. Karr CLA 2018-03-09 11:20:02 EST
I'm now seeing this with Oxygen.2.  I use buffer splitting quite often.  I haven't yet restarted to see if it resolves this.