Bug 254738 - NPE in HierarchyResolver.setFocusType
Summary: NPE in HierarchyResolver.setFocusType
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.5   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: 3.5.1   Edit
Assignee: Jay Arthanareeswaran CLA
QA Contact:
URL:
Whiteboard:
Keywords:
: 263731 264809 268495 284181 284672 (view as bug list)
Depends on:
Blocks:
 
Reported: 2008-11-10 09:41 EST by Sebastian Paul CLA
Modified: 2011-08-24 09:57 EDT (History)
10 users (show)

See Also:


Attachments
Jenny.java, testcase. (1.57 KB, application/octet-stream)
2009-03-04 18:50 EST, Chris West (Faux) CLA
no flags Details
Proposed Patch (5.65 KB, patch)
2009-08-13 00:13 EDT, Jay Arthanareeswaran CLA
no flags Details | Diff
Modified Patch (5.79 KB, patch)
2009-08-14 12:56 EDT, Jay Arthanareeswaran CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Sebastian Paul CLA 2008-11-10 09:41:05 EST
Build ID: I20081030-1917

Steps To Reproduce:
1. Enable "Process Javadoc comments" checkbox in Java->Compiler->Javadoc
2. Attempt to use the "change method signature" refactoring
3. In some instances, Eclipse throws a NPE

More information:
In my special case, I wanted to add another argument. By switching back to build M20080911-1700 (Eclipse 3.4.1), I was able to complete the operation.

Stacktrace:

java.lang.reflect.InvocationTargetException
at org.eclipse.jface.operation.ModalContext.run(ModalContext.java:415)
at org.eclipse.ltk.internal.ui.refactoring.RefactoringWizardDialog2.run(RefactoringWizardDialog2.java:318)
at org.eclipse.ltk.ui.refactoring.RefactoringWizard.createChange(RefactoringWizard.java:583)
at org.eclipse.ltk.ui.refactoring.RefactoringWizard.computeUserInputSuccessorPage(RefactoringWizard.java:422)
at org.eclipse.ltk.ui.refactoring.UserInputWizardPage.computeSuccessorPage(UserInputWizardPage.java:74)
at org.eclipse.ltk.ui.refactoring.UserInputWizardPage.getNextPage(UserInputWizardPage.java:114)
at org.eclipse.ltk.internal.ui.refactoring.RefactoringWizardDialog2.nextOrPreviewPressed(RefactoringWizardDialog2.java:483)
at org.eclipse.ltk.internal.ui.refactoring.RefactoringWizardDialog2.access$0(RefactoringWizardDialog2.java:480)
at org.eclipse.ltk.internal.ui.refactoring.RefactoringWizardDialog2$1.widgetSelected(RefactoringWizardDialog2.java:673)
at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:228)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1003)
at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:3848)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3446)
at org.eclipse.jface.window.Window.runEventLoop(Window.java:825)
at org.eclipse.jface.window.Window.open(Window.java:801)
at org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation$1.run(RefactoringWizardOpenOperation.java:143)
at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:70)
at org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation.run(RefactoringWizardOpenOperation.java:155)
at org.eclipse.jdt.internal.ui.refactoring.actions.RefactoringStarter.activate(RefactoringStarter.java:37)
at org.eclipse.jdt.internal.corext.refactoring.RefactoringExecutionStarter.startChangeSignatureRefactoring(RefactoringExecutionStarter.java:212)
at org.eclipse.jdt.ui.actions.ModifyParametersAction.run(ModifyParametersAction.java:143)
at org.eclipse.jdt.ui.actions.SelectionDispatchAction.dispatchRun(SelectionDispatchAction.java:278)
at org.eclipse.jdt.ui.actions.SelectionDispatchAction.run(SelectionDispatchAction.java:250)
at org.eclipse.jface.action.Action.runWithEvent(Action.java:498)
at org.eclipse.ui.actions.RetargetAction.runWithEvent(RetargetAction.java:230)
at org.eclipse.ui.internal.WWinPluginAction.runWithEvent(WWinPluginAction.java:234)
at org.eclipse.jface.action.ActionContributionItem.handleWidgetSelection(ActionContributionItem.java:584)
at org.eclipse.jface.action.ActionContributionItem.access$2(ActionContributionItem.java:501)
at org.eclipse.jface.action.ActionContributionItem$5.handleEvent(ActionContributionItem.java:412)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1003)
at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:3848)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3446)
at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2382)
at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2346)
at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2198)
at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:493)
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:333)
at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:488)
at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:113)
at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:193)
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:370)
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:549)
at org.eclipse.equinox.launcher.Main.basicRun(Main.java:504)
at org.eclipse.equinox.launcher.Main.run(Main.java:1236)
Caused by: java.lang.NullPointerException
at org.eclipse.jdt.internal.core.hierarchy.HierarchyResolver.setFocusType(HierarchyResolver.java:829)
at org.eclipse.jdt.internal.core.hierarchy.HierarchyResolver.reportHierarchy(HierarchyResolver.java:493)
at org.eclipse.jdt.internal.core.hierarchy.HierarchyResolver.resolve(HierarchyResolver.java:791)
at org.eclipse.jdt.internal.core.hierarchy.IndexBasedHierarchyBuilder.buildForProject(IndexBasedHierarchyBuilder.java:222)
at org.eclipse.jdt.internal.core.hierarchy.IndexBasedHierarchyBuilder.buildFromPotentialSubtypes(IndexBasedHierarchyBuilder.java:328)
at org.eclipse.jdt.internal.core.hierarchy.IndexBasedHierarchyBuilder.build(IndexBasedHierarchyBuilder.java:131)
at org.eclipse.jdt.internal.core.hierarchy.TypeHierarchy.compute(TypeHierarchy.java:300)
at org.eclipse.jdt.internal.core.hierarchy.TypeHierarchy.refresh(TypeHierarchy.java:1255)
at org.eclipse.jdt.internal.core.CreateTypeHierarchyOperation.executeOperation(CreateTypeHierarchyOperation.java:90)
at org.eclipse.jdt.internal.core.JavaModelOperation.run(JavaModelOperation.java:721)
at org.eclipse.jdt.internal.core.JavaModelOperation.runOperation(JavaModelOperation.java:781)
at org.eclipse.jdt.internal.core.SourceType.newTypeHierarchy(SourceType.java:814)
at org.eclipse.jdt.internal.corext.refactoring.rename.RippleMethodFinder2.findAllRippleMethods(RippleMethodFinder2.java:260)
at org.eclipse.jdt.internal.corext.refactoring.rename.RippleMethodFinder2.getAllRippleMethods(RippleMethodFinder2.java:168)
at org.eclipse.jdt.internal.corext.refactoring.rename.RippleMethodFinder2.getRelatedMethods(RippleMethodFinder2.java:161)
at org.eclipse.jdt.internal.corext.refactoring.structure.ChangeSignatureProcessor.checkFinalConditions(ChangeSignatureProcessor.java:816)
at org.eclipse.ltk.core.refactoring.participants.ProcessorBasedRefactoring.checkFinalConditions(ProcessorBasedRefactoring.java:224)
at org.eclipse.ltk.core.refactoring.CheckConditionsOperation.run(CheckConditionsOperation.java:85)
at org.eclipse.ltk.core.refactoring.CreateChangeOperation.run(CreateChangeOperation.java:121)
at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:1800)
at org.eclipse.ltk.internal.ui.refactoring.WorkbenchRunnableAdapter.run(WorkbenchRunnableAdapter.java:87)
at org.eclipse.jface.operation.ModalContext$ModalContextThread.run(ModalContext.java:121)
Root exception:
java.lang.NullPointerException
at org.eclipse.jdt.internal.core.hierarchy.HierarchyResolver.setFocusType(HierarchyResolver.java:829)
at org.eclipse.jdt.internal.core.hierarchy.HierarchyResolver.reportHierarchy(HierarchyResolver.java:493)
at org.eclipse.jdt.internal.core.hierarchy.HierarchyResolver.resolve(HierarchyResolver.java:791)
at org.eclipse.jdt.internal.core.hierarchy.IndexBasedHierarchyBuilder.buildForProject(IndexBasedHierarchyBuilder.java:222)
at org.eclipse.jdt.internal.core.hierarchy.IndexBasedHierarchyBuilder.buildFromPotentialSubtypes(IndexBasedHierarchyBuilder.java:328)
at org.eclipse.jdt.internal.core.hierarchy.IndexBasedHierarchyBuilder.build(IndexBasedHierarchyBuilder.java:131)
at org.eclipse.jdt.internal.core.hierarchy.TypeHierarchy.compute(TypeHierarchy.java:300)
at org.eclipse.jdt.internal.core.hierarchy.TypeHierarchy.refresh(TypeHierarchy.java:1255)
at org.eclipse.jdt.internal.core.CreateTypeHierarchyOperation.executeOperation(CreateTypeHierarchyOperation.java:90)
at org.eclipse.jdt.internal.core.JavaModelOperation.run(JavaModelOperation.java:721)
at org.eclipse.jdt.internal.core.JavaModelOperation.runOperation(JavaModelOperation.java:781)
at org.eclipse.jdt.internal.core.SourceType.newTypeHierarchy(SourceType.java:814)
at org.eclipse.jdt.internal.corext.refactoring.rename.RippleMethodFinder2.findAllRippleMethods(RippleMethodFinder2.java:260)
at org.eclipse.jdt.internal.corext.refactoring.rename.RippleMethodFinder2.getAllRippleMethods(RippleMethodFinder2.java:168)
at org.eclipse.jdt.internal.corext.refactoring.rename.RippleMethodFinder2.getRelatedMethods(RippleMethodFinder2.java:161)
at org.eclipse.jdt.internal.corext.refactoring.structure.ChangeSignatureProcessor.checkFinalConditions(ChangeSignatureProcessor.java:816)
at org.eclipse.ltk.core.refactoring.participants.ProcessorBasedRefactoring.checkFinalConditions(ProcessorBasedRefactoring.java:224)
at org.eclipse.ltk.core.refactoring.CheckConditionsOperation.run(CheckConditionsOperation.java:85)
at org.eclipse.ltk.core.refactoring.CreateChangeOperation.run(CreateChangeOperation.java:121)
at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:1800)
at org.eclipse.ltk.internal.ui.refactoring.WorkbenchRunnableAdapter.run(WorkbenchRunnableAdapter.java:87)
at org.eclipse.jface.operation.ModalContext$ModalContextThread.run(ModalContext.java:121)
Comment 1 Jerome Lanneluc CLA 2008-11-13 12:48:07 EST
Looking at the code, I don't see how this can happen. Would you have more detail steps to reproduce the problem? A small workspace showing the problem would be very welcome.
Comment 2 Sebastian Paul CLA 2008-11-14 03:33:19 EST
Sorry, cannot send my whole workspace - it's too big. And I don't have time at the moment to find a small example. But I can tell as much as I can:
I changed the signature of an interface method. The interface was implemented by several classes, and there were derived classes that overrode the implemented method. I just renamed a parameter, as its meaning changed.
I hope that helps... Maybe I find the time to provide a workspace.
Comment 3 Benjamin Muskalla CLA 2009-03-04 12:57:44 EST
N20090215-2000

Just ran into this while editing java code. No steps either - sorry. But I think bug 264809 and bug 263731 suffer from the same problem.
Comment 4 Frederic Fusier CLA 2009-03-04 13:02:01 EST
*** Bug 264809 has been marked as a duplicate of this bug. ***
Comment 5 Frederic Fusier CLA 2009-03-04 13:02:46 EST
*** Bug 263731 has been marked as a duplicate of this bug. ***
Comment 6 Chris West (Faux) CLA 2009-03-04 18:50:54 EST
Created attachment 127580 [details]
Jenny.java, testcase.

I've managed to testcase this; mouseover or attempt to rename void Jenny.from(...).new John() {...}.where(...).new Alex() {...}.equals(String value) (line 88).

Before complaining about the length of this testcase (100 lines), note that, when it starts working (i.e. you remove something that's causing it to break), you need to /restart Eclipse/.  That's more than slightly irritating.

I'm starting to think Eclipse's compiler has something against my code style.

Also worth noting that the debugger really hates some methods in the class Jenny was derived from, won't give local variables, won't breakpoint.. ("Cannot create method breakpoint, method signature not available.").

Happens in a brand new Java project with:
eclipse.buildId=I20081211-1908
java.version=1.6.0_12
java.vendor=Sun Microsystems Inc.
BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=en_GB
Command-line arguments:  -os win32 -ws win32 -arch x86_64

java.lang.NullPointerException
at org.eclipse.jdt.internal.core.hierarchy.HierarchyResolver.setFocusType(HierarchyResolver.java:829)
at org.eclipse.jdt.internal.core.hierarchy.HierarchyResolver.reportHierarchy(HierarchyResolver.java:493)
at org.eclipse.jdt.internal.core.hierarchy.HierarchyResolver.resolve(HierarchyResolver.java:791)
at org.eclipse.jdt.internal.core.hierarchy.HierarchyResolver.resolve(HierarchyResolver.java:584)
at org.eclipse.jdt.internal.core.hierarchy.HierarchyBuilder.buildSupertypes(HierarchyBuilder.java:115)
at org.eclipse.jdt.internal.core.hierarchy.IndexBasedHierarchyBuilder.build(IndexBasedHierarchyBuilder.java:135)
at org.eclipse.jdt.internal.core.hierarchy.TypeHierarchy.compute(TypeHierarchy.java:300)
at org.eclipse.jdt.internal.core.hierarchy.TypeHierarchy.refresh(TypeHierarchy.java:1255)
at org.eclipse.jdt.internal.core.CreateTypeHierarchyOperation.executeOperation(CreateTypeHierarchyOperation.java:90)
at org.eclipse.jdt.internal.core.JavaModelOperation.run(JavaModelOperation.java:721)
at org.eclipse.jdt.internal.core.JavaModelOperation.runOperation(JavaModelOperation.java:781)
at org.eclipse.jdt.internal.core.SourceType.newSupertypeHierarchy(SourceType.java:726)
at org.eclipse.jdt.internal.core.SourceType.newSupertypeHierarchy(SourceType.java:678)
at org.eclipse.jdt.internal.corext.util.SuperTypeHierarchyCache.getTypeHierarchy(SuperTypeHierarchyCache.java:139)
at org.eclipse.jdt.internal.corext.util.SuperTypeHierarchyCache.getTypeHierarchy(SuperTypeHierarchyCache.java:91)
at org.eclipse.jdt.internal.ui.text.javadoc.JavadocContentAccess2$JavadocLookup.getTypeHierarchy(JavadocContentAccess2.java:383)
at org.eclipse.jdt.internal.ui.text.javadoc.JavadocContentAccess2$JavadocLookup.getInheritedDescription(JavadocContentAccess2.java:337)
at org.eclipse.jdt.internal.ui.text.javadoc.JavadocContentAccess2$JavadocLookup.getInheritedMainDescription(JavadocContentAccess2.java:254)
at org.eclipse.jdt.internal.ui.text.javadoc.JavadocContentAccess2.toHTML(JavadocContentAccess2.java:768)
at org.eclipse.jdt.internal.ui.text.javadoc.JavadocContentAccess2.javadoc2HTML(JavadocContentAccess2.java:620)
at org.eclipse.jdt.internal.ui.text.javadoc.JavadocContentAccess2.getHTMLContentFromSource(JavadocContentAccess2.java:566)
at org.eclipse.jdt.internal.ui.text.javadoc.JavadocContentAccess2.getHTMLContent(JavadocContentAccess2.java:458)
at org.eclipse.jdt.internal.ui.text.java.hover.JavadocHover.getHoverInfo(JavadocHover.java:553)
at org.eclipse.jdt.internal.ui.text.java.hover.JavadocHover.internalGetHoverInfo(JavadocHover.java:510)
at org.eclipse.jdt.internal.ui.text.java.hover.JavadocHover.getHoverInfo2(JavadocHover.java:495)
at org.eclipse.jdt.internal.ui.text.java.hover.BestMatchHover.getHoverInfo2(BestMatchHover.java:129)
at org.eclipse.jdt.internal.ui.text.java.hover.JavaEditorTextHoverProxy.getHoverInfo2(JavaEditorTextHoverProxy.java:82)
at org.eclipse.jface.text.TextViewerHoverManager$4.run(TextViewerHoverManager.java:166)
Comment 7 Chris West (Faux) CLA 2009-05-19 18:46:22 EDT
White-box testcase:

public class Parent
{
	public void parentmethod()
	{
		new Object() // nested class 1 (Parent$1)
		{
			void nestedonemethod()
			{
				new Object() // nested class 2 (Parent$1$1)
				{
					public int hashCode()
					{
						return 0;
					}
				};
			}
		};
	}
}

// crank up the CU's annotation count
@Deprecated
class Dep
{
	@Deprecated void a() {}
	@Deprecated void b() {}
	@Deprecated void c() {}
	@Deprecated void d() {}
	@Deprecated void e() {}
	@Deprecated void f() {}
	@Deprecated void g() {}
	@Deprecated void h() {}
	@Deprecated void i() {}
	@Deprecated void j() {}
}

What's Going Wrong:

1. When there are > 10 annotations in a CU (org.eclipse.jdt.internal.compiler.parser.SourceTypeConverter.convert(ISourceType[], CompilationResult) line 115), Eclipse elects to do a "diet" parse, which skips method-local anonymous classes, resulting in a CompilationUnitDeclaration of:

public class Parent {
  public Parent() {
  }
  public void parentmethod() {
  }
}
@Deprecated class Dep {
 ..


instead of:
public class Parent {
  public Parent() {
  }
  public void parentmethod() {
    new Object() {
      () {
      }
      void nestedonemethod() {
        new Object() {
          () {
          }
          public int hashCode() {
          }
        };
      }
    };
  }
}
@Deprecated class Dep {
 ...


2. (unlikely) ASTNodeFinder (org.eclipse.jdt.internal.core.hierarchy.HierarchyResolver.resolve(Openable[], HashSet, IProgressMonitor) line 721) can't find class <anonymous #1> [in nestedonemethod() [in <anonymous #1> [in parentmethod() [in Parent [...]:

// remember type declaration of focus if local/anonymous early (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=210498)
...	
		focusLocalType = new ASTNodeFinder(focusUnit).findType(focus);

3. ASTNodeFinder's failure causes org.eclipse.jdt.internal.core.hierarchy.HierarchyResolver.reportHierarchy(IType, TypeDeclaration, ReferenceBinding) to call HierarchyResolver.setFocusType(char[][]) with [[P, a, r, e, n, t, $, 1, $, 1]].

4. This method calls getMemberType("1") (from the anonymous class number) on the focus type to get the new focus type.  The new focus type isn't available, so is null.  Trying to do the second level of nesting -> NPE.
Comment 8 Markus Keller CLA 2009-07-27 07:03:47 EDT
*** Bug 284181 has been marked as a duplicate of this bug. ***
Comment 9 Dani Megert CLA 2009-07-30 07:08:54 EDT
Olivier, this is pretty bad as the type hierarchy gets into inconsistent state (see e.g. bug 284672). We should fix this for 3.5.1.
Comment 10 Dani Megert CLA 2009-07-30 07:10:01 EDT
*** Bug 284672 has been marked as a duplicate of this bug. ***
Comment 11 Dani Megert CLA 2009-07-30 07:10:53 EDT
Bug 284672 also contains a little test project with steps to reproduce.
Comment 12 Dani Megert CLA 2009-07-30 07:11:35 EDT
Setting target, so it doesn't get lost.
Comment 13 Olivier Thomann CLA 2009-07-30 08:41:45 EDT
Jay, please investigate for 3.5.1.
Comment 14 Jay Arthanareeswaran CLA 2009-08-13 00:13:04 EDT
Created attachment 144345 [details]
Proposed Patch

Attaching the proposed fix with test cases.
Comment 15 Olivier Thomann CLA 2009-08-13 12:19:33 EDT
Looking at the patch, I have one comment.
You added this test:
if ((this.flags & METHOD) == 0) {
return new Parser(this.problemReporter, true).dietParse(this.cu, compilationResult);
}

to disable diet parse. I wonder if you should not use the LOCAL_TYPE flag instead.
METHOD is widely used and this might have a performance impact.
I agree that this would only be the case when more than 10 annotations are used.

Jay, let me know what you think.
Comment 16 Jay Arthanareeswaran CLA 2009-08-14 12:56:41 EDT
Created attachment 144556 [details]
Modified Patch

I totally agree on that, Olivier. It's my misunderstanding of the LOCAL_TYPE that caused the error. We need to check only for LOCAL_TYPE there. Please look at the modified patch.
Comment 17 Olivier Thomann CLA 2009-08-17 14:55:29 EDT
Thanks Jay.

Released for 3.5.1.
Released for 3.6M2.

Same patch applies to both HEAD and 3.5 maintenance.
Regression test added in:
org.eclipse.jdt.core.tests.model.TypeHierarchyTests#testBug254738
Comment 18 Olivier Thomann CLA 2009-08-27 12:31:20 EDT
Verified for 3.5.1RC2 using M20090826-1100.
Leave as RESOLVED FIXED as it will be closed as VERIFIED FIXED in 3.6M2 verification.
Comment 19 Olivier Thomann CLA 2009-08-28 11:33:36 EDT
Verified.
Comment 20 Olivier Thomann CLA 2009-09-13 20:17:12 EDT
*** Bug 268495 has been marked as a duplicate of this bug. ***
Comment 21 Olivier Thomann CLA 2009-09-16 09:45:27 EDT
Verified for 3.6M2 using I20090915-0100.
Comment 22 Dani Megert CLA 2011-08-24 03:12:38 EDT
This is back. See bug 355605.
Comment 23 Olivier Thomann CLA 2011-08-24 09:57:59 EDT
(In reply to comment #22)
> This is back. See bug 355605.
Even if the NPE seems to be at the same location, the stack trace is quite different.