Bug 129193 [JFace] Setting the sorter on AbstractTreeViewer before input can cause NPE
I have a scenario with a subclass of TreePathViewerSorter is set on a subclass of AbstractTreeViewer. AbstractTreeViewer.setSorter() calls refresh, which eventually ends up here: // AbstractTreeViewer: /* (non-Javadoc) * @see org.eclipse.jface.viewers.StructuredViewer#getSortedChildren(java.lang.Object) */ protected Object[] getSortedChildren(Object parentElementOrTreePath) { Object[] result = getFilteredChildren(parentElementOrTreePath); ViewerSorter sorter = getSorter(); if (sorter instanceof TreePathViewerSorter) { TreePathViewerSorter tpvs = (TreePathViewerSorter) sorter; // be sure we're not modifying the original array from the model result = (Object[]) result.clone(); TreePath path = null; if (parentElementOrTreePath instanceof TreePath) { path = (TreePath) parentElementOrTreePath; } else { (1) Object parent = parentElementOrTreePath; (2) Widget w = internalGetWidgetToSelect(parent); if (w != null) { path = internalGetSorterParentPath(w, sorter); } if (path == null) path = TreePath.EMPTY.createChildPath(parentElementOrTreePath); } tpvs.sort(this, path, result); } else if (sorter != null) { // be sure we're not modifying the original array from the model result = (Object[]) result.clone(); sorter.sort(this, result); } return result; } At line (1) parent is null and at line (2) it eventually gets down into findItems(): // StructuredViewer: protected final Widget[] findItems(Object element) { Widget result = doFindInputItem(element); if (result != null) return new Widget[] { result }; // if we have an element map use it, otherwise search for the item. if (usingElementMap()) { (3) Object widgetOrWidgets = elementMap.get(element); if (widgetOrWidgets==null) { return NO_WIDGETS; } else if (widgetOrWidgets instanceof Widget) { return new Widget[] {(Widget) widgetOrWidgets}; } else { return (Widget[])widgetOrWidgets; } } result = doFindItem(element); return result == null ? NO_WIDGETS : new Widget[] { result }; } Here at (3), element is null, and the HashMap throws an NPE when trying to call key.hashCode() (since key is null).
bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/AbstractTreeViewer.java
* @see org.eclipse.jface.viewers.StructuredViewer#getFilteredChildren(java.lang.Object)
	 */
	protected Object[] getFilteredChildren(Object parentElementOrTreePath) {
		Object[] result = getRawChildren(parentElementOrTreePath);
		ViewerFilter[] filters = getFilters();
		for (int i = 0; i < filters.length; i++) {
			ViewerFilter filter = filters[i];
			result = filter.filter(this, parentElementOrTreePath, result);
		}
		return result;
	}
	
    /**
     * Adds the given child element to this viewer as a child of the given
     * parent element. If this viewer does not have a sorter, the element is
     * added at the end of the parent's list of children; otherwise, the
     * element is inserted at the appropriate position.
     * <p>
     * This method should be called (by the content provider) when a single
     * element has been added to the model, in order to cause the viewer to
     * accurately reflect the model. This method only affects the viewer, not
     * the model. Note that there is another method for efficiently processing
     * the simultaneous addition of multiple elements.
     * </p>
     * 
     * @param parentElementOrTreePath
     *           the parent element or path
     * @param childElement
     *           the child element
     */