Community
Participate
Working Groups
Build Identifier: 20090920-1017 When calling viewer.setContentProvider(viewer.getContentProvider()) on a ComboViewer that contains an ObservableListContentProvider a NullPointerException is thrown in a jface databinding internal class. Even worse, when trying to decorate the contentprovider by adding an element that represents a null value, I get the same exception. Workaround: set the right IStructuredContentProvider once. Exception in thread "main" java.lang.NullPointerException at org.eclipse.jface.internal.databinding.viewers.ObservableCollectionContentProvider.setViewer(ObservableCollectionContentProvider.java:162) at org.eclipse.jface.internal.databinding.viewers.ObservableCollectionContentProvider.inputChanged(ObservableCollectionContentProvider.java:155) at org.eclipse.jface.databinding.viewers.ObservableListContentProvider$Impl.inputChanged(ObservableListContentProvider.java:57) at org.eclipse.jface.databinding.viewers.ObservableListContentProvider.inputChanged(ObservableListContentProvider.java:171) at org.eclipse.jface.snippets.viewers.SnippetComboViewerBug$NullElementStructuredContentProviderDecorator.inputChanged(SnippetComboViewerBug.java:85) at org.eclipse.jface.viewers.ContentViewer.setContentProvider(ContentViewer.java:251) at org.eclipse.jface.viewers.StructuredViewer.setContentProvider(StructuredViewer.java:1611) at org.eclipse.jface.snippets.viewers.SnippetComboViewerBug.createPartControl(SnippetComboViewerBug.java:105) at org.eclipse.jface.snippets.viewers.SnippetComboViewerBug$1.run(SnippetComboViewerBug.java:120) at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332) at org.eclipse.jface.snippets.viewers.SnippetComboViewerBug.main(SnippetComboViewerBug.java:115) Reproducible: Always Steps to Reproduce: 1. Create a ComboViewer with an ObservableListContentProvider and some input. 2. Call viewer.setContentProvider(viewer.getContentProvider()) Alternatively, run the attached snippet.
Created attachment 175477 [details] Self contained snippet which shows Bug 321209
SlowStrider: the problem is that when you set a new content provider on a ContentViewer, the viewer disposes the old IContentProvider before setting up the new one. However you're wrapping the old content provider in the new one, so by the time the new one is getting initialized, the provider it wraps is disposed and no longer safe to use. viewer.setContentProvider(new ObservableListContentProvider()); viewer.setInput(new WritableList(Arrays.asList("male", "female"), String.class)); // Throws a NullPointerException in a jface databinding internal class. // Workaround: set the decorated content provider when first // calling viewer.setContentProvider. viewer.setContentProvider( new NullElementStructuredContentProviderDecorator( (IStructuredContentProvider) viewer.getContentProvider())); A safer workaround is to just use a new Observable<List|Set>ContentProvider instance each time you change the content provider: viewer.setContentProvider( new NullElementStructuredContentProviderDecorator( new ObservableListContentProvider())); And this will definitely break with the DataBinding content providers: viewer.setContentProvider(viewer.getContentProvider()); I've added documentation to the Observable(List|Set)(Tree)?ContentProvider.dispose() methods explaining that they become unusable after disposal, and that the viewer disposes replaced content providers.