Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 334636 - [TabbedProperties] NullPointerException in TabbedPropertySheetPage.disposeContributor
Summary: [TabbedProperties] NullPointerException in TabbedPropertySheetPage.disposeCon...
Status: VERIFIED FIXED
Alias: None
Product: Platform
Classification: Eclipse Project
Component: UI (show other bugs)
Version: 3.7   Edit
Hardware: All All
: P3 normal (vote)
Target Milestone: 3.7 M6   Edit
Assignee: Dani Megert CLA
QA Contact: Anthony Hunter CLA
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-01-18 08:37 EST by Heiko Böttger CLA
Modified: 2011-03-14 07:05 EDT (History)
5 users (show)

See Also:


Attachments
Test Case RCP app (23.15 KB, application/octet-stream)
2011-01-28 10:48 EST, CLA
no flags Details
Better version of test app (23.11 KB, application/octet-stream)
2011-01-28 10:54 EST, CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Heiko Böttger CLA 2011-01-18 08:37:07 EST
Build Identifier: I20101028-1441

java.lang.NullPointerException
	at org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage.disposeContributor(TabbedPropertySheetPage.java:464)
	at org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage.dispose(TabbedPropertySheetPage.java:482)
	at org.eclipse.ui.views.properties.PropertySheet.doDestroyPage(PropertySheet.java:225)
	at org.eclipse.ui.part.PageBookView.removePage(PageBookView.java:857)
	at org.eclipse.ui.part.PageBookView.partClosed(PageBookView.java:784)
	at org.eclipse.ui.views.properties.PropertySheet.partClosed(PropertySheet.java:284)
	at org.eclipse.ui.part.PageBookView$4.partClosed(PageBookView.java:1018)
	at org.eclipse.ui.internal.PartListenerList2$3.run(PartListenerList2.java:100)
	at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
	at org.eclipse.core.runtime.Platform.run(Platform.java:888)
	at org.eclipse.ui.internal.PartListenerList2.fireEvent(PartListenerList2.java:55)
	at org.eclipse.ui.internal.PartListenerList2.firePartClosed(PartListenerList2.java:98)
	at org.eclipse.ui.internal.PartService.firePartClosed(PartService.java:227)
	at org.eclipse.ui.internal.WorkbenchPagePartList.firePartClosed(WorkbenchPagePartList.java:39)
	at org.eclipse.ui.internal.PartList.partClosed(PartList.java:274)
	at org.eclipse.ui.internal.PartList.removePart(PartList.java:186)
	at org.eclipse.ui.internal.WorkbenchPage.disposePart(WorkbenchPage.java:1720)
	at org.eclipse.ui.internal.WorkbenchPage.handleDeferredEvents(WorkbenchPage.java:1426)
	at org.eclipse.ui.internal.WorkbenchPage.deferUpdates(WorkbenchPage.java:1410)
	at org.eclipse.ui.internal.WorkbenchPage.closeEditors(WorkbenchPage.java:1384)
	at org.eclipse.ui.internal.WorkbenchPage.closeEditor(WorkbenchPage.java:1439)
	at org.eclipse.ui.internal.EditorPane.doHide(EditorPane.java:61)
	at org.eclipse.ui.internal.PartStack.close(PartStack.java:537)
	at org.eclipse.ui.internal.EditorStack.close(EditorStack.java:206)
	at org.eclipse.ui.internal.PartStack$1.close(PartStack.java:120)
	at org.eclipse.ui.internal.presentations.util.TabbedStackPresentation$1.handleEvent(TabbedStackPresentation.java:83)
	at org.eclipse.ui.internal.presentations.util.AbstractTabFolder.fireEvent(AbstractTabFolder.java:269)
	at org.eclipse.ui.internal.presentations.util.AbstractTabFolder.fireEvent(AbstractTabFolder.java:278)
	at org.eclipse.ui.internal.presentations.defaultpresentation.DefaultTabFolder.access$1(DefaultTabFolder.java:1)
	at org.eclipse.ui.internal.presentations.defaultpresentation.DefaultTabFolder$1.closeButtonPressed(DefaultTabFolder.java:71)
	at org.eclipse.ui.internal.presentations.PaneFolder.notifyCloseListeners(PaneFolder.java:631)
	at org.eclipse.ui.internal.presentations.PaneFolder$3.close(PaneFolder.java:206)
	at org.eclipse.swt.custom.CTabFolder.onMouse(CTabFolder.java:1598)
	at org.eclipse.swt.custom.CTabFolder$1.handleEvent(CTabFolder.java:261)
	at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1053)
	at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:4084)
	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3675)
	at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2629)
	at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2593)
	at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2427)
	at org.eclipse.ui.internal.Workbench$7.run(Workbench.java:670)
	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
	at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:663)
	at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
	at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:115)
	at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:369)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
	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.equinox.launcher.Main.invokeFramework(Main.java:621)
	at org.eclipse.equinox.launcher.Main.basicRun(Main.java:576)
	at org.eclipse.equinox.launcher.Main.run(Main.java:1409)

May be the same problem as in #333254 however on dispose.

Reproducible: Always
Comment 1 Remy Suen CLA 2011-01-18 08:46:01 EST
(In reply to comment #0)
> Reproducible: Always

And what steps does one take to reproduce this always reproducible problem?
Comment 2 Heiko Böttger CLA 2011-01-19 05:18:25 EST
(In reply to comment #1)
> (In reply to comment #0)
> > Reproducible: Always
> 
> And what steps does one take to reproduce this always reproducible problem?

I must appologize, it seems didn't that I set the option accidentaly to "always reproducible". I have no I idea how I created this, but after it occured the first time, it happend everytime i closed an editor until restarting eclipse.

Thanks for asking.
Comment 3 CLA 2011-01-28 09:10:32 EST
I can confirm this on Windows 7 and Mac OS X Carbon and Cocoa32. Using Version: 3.7.0 Build id: I20110127-1100.

Stack Trace:

!ENTRY org.eclipse.ui.workbench 4 0 2011-01-28 14:07:56.053
!MESSAGE An unexpected exception was thrown.
!STACK 0
java.lang.NullPointerException
	at org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage.disposeContributor(TabbedPropertySheetPage.java:464)
	at org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage.dispose(TabbedPropertySheetPage.java:482)
	at org.eclipse.ui.views.properties.PropertySheet.doDestroyPage(PropertySheet.java:225)
	at org.eclipse.ui.part.PageBookView.removePage(PageBookView.java:857)
	at org.eclipse.ui.part.PageBookView.dispose(PageBookView.java:515)
	at org.eclipse.ui.views.properties.PropertySheet.dispose(PropertySheet.java:185)
	at org.eclipse.ui.internal.WorkbenchPartReference.doDisposePart(WorkbenchPartReference.java:737)
	at org.eclipse.ui.internal.ViewReference.doDisposePart(ViewReference.java:104)
	at org.eclipse.ui.internal.WorkbenchPartReference.dispose(WorkbenchPartReference.java:684)
	at org.eclipse.ui.internal.WorkbenchPage.disposePart(WorkbenchPage.java:1721)
	at org.eclipse.ui.internal.WorkbenchPage.partRemoved(WorkbenchPage.java:1713)
	at org.eclipse.ui.internal.ViewFactory.releaseView(ViewFactory.java:257)
	at org.eclipse.ui.internal.Perspective.hideView(Perspective.java:606)
	at org.eclipse.ui.internal.WorkbenchPage.hideView(WorkbenchPage.java:2387)
	at org.eclipse.ui.internal.ViewPane.doHide(ViewPane.java:213)
	at org.eclipse.ui.internal.PartStack.close(PartStack.java:537)
	at org.eclipse.ui.internal.PartStack.close(PartStack.java:520)
	at org.eclipse.ui.internal.PartStack$1.close(PartStack.java:120)
	at org.eclipse.ui.internal.presentations.util.TabbedStackPresentation$1.handleEvent(TabbedStackPresentation.java:83)
	at org.eclipse.ui.internal.presentations.util.AbstractTabFolder.fireEvent(AbstractTabFolder.java:269)
	at org.eclipse.ui.internal.presentations.util.AbstractTabFolder.fireEvent(AbstractTabFolder.java:278)
	at org.eclipse.ui.internal.presentations.defaultpresentation.DefaultTabFolder.access$1(DefaultTabFolder.java:1)
	at org.eclipse.ui.internal.presentations.defaultpresentation.DefaultTabFolder$1.closeButtonPressed(DefaultTabFolder.java:71)
	at org.eclipse.ui.internal.presentations.PaneFolder.notifyCloseListeners(PaneFolder.java:631)
	at org.eclipse.ui.internal.presentations.PaneFolder$3.close(PaneFolder.java:206)
	at org.eclipse.swt.custom.CTabFolder.onMouse(CTabFolder.java:1598)
	at org.eclipse.swt.custom.CTabFolder$1.handleEvent(CTabFolder.java:261)
	at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1053)
	at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:4126)
	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3715)
	at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2697)
	at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2661)
	at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2495)
	at org.eclipse.ui.internal.Workbench$7.run(Workbench.java:674)
	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
	at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:667)
	at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
	at uk.ac.bolton.archimate.editor.Application.start(Application.java:66)
	at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:344)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:622)
	at org.eclipse.equinox.launcher.Main.basicRun(Main.java:577)
	at org.eclipse.equinox.launcher.Main.run(Main.java:1410)
	at org.eclipse.equinox.launcher.Main.main(Main.java:1386)
Comment 4 CLA 2011-01-28 09:19:11 EST
I can reproduce this 100% of the time in my RCP application:

1. I select an object in my RCP app which updates the Tabbed Properties View with one set of AbstractPropertySection sections.

2. Then I select another object in my app which then updates the Tabbed Properties View with a different set of AbstractPropertySection sections.

3. I close the Properties Window.

TabbedPropertyRegistry.dispose() is being called before TabbedPropertySheetPage.disposeContributor() so a NPE at line 464:

registry.getLabelProvider().removeListener(this);
Comment 5 CLA 2011-01-28 10:09:54 EST
TabbedPropertyRegistry.dispose()

"@since 3.7" - would explain why this is showing now.

Some more information:

This only happens when I switch between a different ITabbedPropertySheetPageContributor ViewPart or EditorPart that shared the same Contributor ID in my app.

If I open an instance of our DiagramEditor class (extends EditorPart) which implements ITabbedPropertySheetPageContributor thus:

    public String getContributorId() {
        return "uk.ac.bolton.archimate.editor";
    }

Then the Tabbed Properties View works just fine whatever I throw at it, and whether I re-open and close it.

However, the moment I switch to a View in the app (extends ViewPart), which also implements ITabbedPropertySheetPageContributor thus:

    public String getContributorId() {
        return "uk.ac.bolton.archimate.editor";
    }

And then close the Properties View then I get the NPE.

I can trace this to:
 TabbedPropertyRegistryFactory.disposeRegistry(ITabbedPropertySheetPageContributor target):
Comment 6 CLA 2011-01-28 10:48:04 EST
Created attachment 187851 [details]
Test Case RCP app

Here's a simple reproducible test case. It's a basic RCP application based on the "RCP application with a View" wizard template.

1. Launch the RCP application
2. There are 2 Views and the Properties View open
3. Select tree nodes on each View to update Properties View (it will be blank, doesn't matter)
4. Close the Properties View

NPE
Comment 7 CLA 2011-01-28 10:54:22 EST
Created attachment 187852 [details]
Better version of test app

Sorry, the plugin.xml file got mangled in that one, please try this one.
Comment 8 CLA 2011-01-28 11:03:32 EST
I just noticed that the original reported reported this against Eclipse 3.5.2. This is only happening for me in Eclipse 3.7.0. Wondering if reporter's version is a mistake?
Comment 9 CLA 2011-01-28 11:11:47 EST
If the "Version" field of this bug report refers to the Eclipse version then it should be changed to "3.7.0", not "3.5.2".  "3.5.2" refers to the version of the org.eclipse.ui.views.properties.tabbed;bundle-version="3.5.200" 

This is important to note as the bug only occurs in Eclipse 3.7.
Comment 10 CLA 2011-01-28 18:55:53 EST
I wonder if the call to data.registry.dispose(); in TabbedPropertyRegistryFactory should be moved into the isEmpty() check of references thus:

	public void disposeRegistry(ITabbedPropertySheetPageContributor target) {
		/**
		 * Get the contributor id from the ITabbedPropertySheetPageContributor
		 * interface
		 */
		String key = target.getContributorId();
		CacheData data = (CacheData) idToCacheData.get(key);
		if (data != null) {
			data.references.remove(target);
			if (data.references.isEmpty()) {
			        data.registry.dispose();    // <------ HERE
				idToCacheData.remove(key);
			}
		}
	}
Comment 11 CLA 2011-01-28 19:15:29 EST
(In reply to comment #10)
> I wonder if the call to data.registry.dispose(); in
> TabbedPropertyRegistryFactory should be moved into the isEmpty() check of
> references thus:
> 
>     public void disposeRegistry(ITabbedPropertySheetPageContributor target) {
>         /**
>          * Get the contributor id from the ITabbedPropertySheetPageContributor
>          * interface
>          */
>         String key = target.getContributorId();
>         CacheData data = (CacheData) idToCacheData.get(key);
>         if (data != null) {
>             data.references.remove(target);
>             if (data.references.isEmpty()) {
>                     data.registry.dispose();    // <------ HERE
>                 idToCacheData.remove(key);
>             }
>         }
>     }

And the answer is yes. I tested it and this works. What I don't know is if this has any unwanted side-effects.
Comment 12 CLA 2011-01-31 06:58:22 EST
This relates to Bug #275702 So I guess it affects 3.6.2?
Comment 13 Dani Megert CLA 2011-01-31 07:02:40 EST
(In reply to comment #12)
> This relates to Bug #275702 So I guess it affects 3.6.2?
No, the fix for bug 275702 was only put into 3.7.
Comment 14 Dani Megert CLA 2011-01-31 08:17:14 EST
Fixed in HEAD (TabbedPropertyRegistryFactory.java, rev. 1.5).
Comment 15 Jesse CLA 2011-03-09 14:12:25 EST
Verified in build I20110307-2110. NPE is gone.