Bug 101955 - NullPointerException after invoking extract method
Summary: NullPointerException after invoking extract method
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.1   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: 3.1.1   Edit
Assignee: Olivier Thomann CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-06-27 21:18 EDT by Khaled Agrama CLA
Modified: 2005-09-26 12:18 EDT (History)
4 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Khaled Agrama CLA 2005-06-27 21:18:39 EDT
3.1RC4 (Build id: I20050624-1300)

When trying to extract a method I get the error:
"An unexpected exception occurred during condition checking."

Unfortunately I don't have a reproducible test case; the exception happens when
trying to extract a method out of one particular area of my code but not in
other similar areas.

from the error log:

java.lang.reflect.InvocationTargetException
	at org.eclipse.jface.operation.ModalContext.run(ModalContext.java:327)
	at
org.eclipse.jface.dialogs.ProgressMonitorDialog.run(ProgressMonitorDialog.java:447)
	at
org.eclipse.ui.internal.progress.ProgressMonitorJobsDialog.run(ProgressMonitorJobsDialog.java:261)
	at org.eclipse.ui.internal.progress.ProgressManager$3.run(ProgressManager.java:861)
	at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:69)
	at
org.eclipse.ui.internal.progress.ProgressManager.busyCursorWhile(ProgressManager.java:895)
	at
org.eclipse.ui.internal.progress.ProgressManager.busyCursorWhile(ProgressManager.java:871)
	at
org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation.checkInitialConditions(RefactoringWizardOpenOperation.java:150)
	at
org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation.access$0(RefactoringWizardOpenOperation.java:146)
	at
org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation$1.run(RefactoringWizardOpenOperation.java:116)
	at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:69)
	at
org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation.run(RefactoringWizardOpenOperation.java:138)
	at
org.eclipse.jdt.internal.ui.refactoring.actions.RefactoringStarter.activate(RefactoringStarter.java:40)
	at org.eclipse.jdt.ui.actions.ExtractMethodAction.run(ExtractMethodAction.java:84)
	at
org.eclipse.jdt.ui.actions.SelectionDispatchAction.dispatchRun(SelectionDispatchAction.java:226)
	at
org.eclipse.jdt.ui.actions.SelectionDispatchAction.run(SelectionDispatchAction.java:198)
	at org.eclipse.jface.action.Action.runWithEvent(Action.java:996)
	at org.eclipse.ui.commands.ActionHandler.execute(ActionHandler.java:182)
	at
org.eclipse.ui.internal.handlers.LegacyHandlerWrapper.execute(LegacyHandlerWrapper.java:108)
	at org.eclipse.core.commands.Command.execute(Command.java:311)
	at
org.eclipse.core.commands.ParameterizedCommand.execute(ParameterizedCommand.java:396)
	at
org.eclipse.ui.internal.keys.WorkbenchKeyboard.executeCommand(WorkbenchKeyboard.java:459)
	at org.eclipse.ui.internal.keys.WorkbenchKeyboard.press(WorkbenchKeyboard.java:781)
	at
org.eclipse.ui.internal.keys.WorkbenchKeyboard.processKeyEvent(WorkbenchKeyboard.java:828)
	at
org.eclipse.ui.internal.keys.WorkbenchKeyboard.filterKeySequenceBindings(WorkbenchKeyboard.java:550)
	at
org.eclipse.ui.internal.keys.WorkbenchKeyboard.access$3(WorkbenchKeyboard.java:493)
	at
org.eclipse.ui.internal.keys.WorkbenchKeyboard$KeyDownFilter.handleEvent(WorkbenchKeyboard.java:117)
	at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:66)
	at org.eclipse.swt.widgets.Display.filterEvent(Display.java:917)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:842)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:867)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:852)
	at org.eclipse.swt.widgets.Widget.sendKeyEvent(Widget.java:880)
	at org.eclipse.swt.widgets.Widget.sendKeyEvent(Widget.java:876)
	at org.eclipse.swt.widgets.Widget.wmKeyDown(Widget.java:1475)
	at org.eclipse.swt.widgets.Control.WM_KEYDOWN(Control.java:3348)
	at org.eclipse.swt.widgets.Control.windowProc(Control.java:3067)
	at org.eclipse.swt.widgets.Display.windowProc(Display.java:3706)
	at org.eclipse.swt.internal.win32.OS.DispatchMessageW(Native Method)
	at org.eclipse.swt.internal.win32.OS.DispatchMessage(OS.java:1656)
	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:2711)
	at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:1699)
	at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:1663)
	at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:367)
	at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:143)
	at org.eclipse.ui.internal.ide.IDEApplication.run(IDEApplication.java:103)
	at
org.eclipse.core.internal.runtime.PlatformActivator$1.run(PlatformActivator.java:226)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:376)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:163)
	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:585)
	at org.eclipse.core.launcher.Main.invokeFramework(Main.java:334)
	at org.eclipse.core.launcher.Main.basicRun(Main.java:278)
	at org.eclipse.core.launcher.Main.run(Main.java:973)
	at org.eclipse.core.launcher.Main.main(Main.java:948)
Caused by: java.lang.NullPointerException
	at org.eclipse.jdt.internal.corext.dom.Bindings.equals(Bindings.java:88)
	at
org.eclipse.jdt.internal.corext.refactoring.code.SnippetFinder$Matcher.match(SnippetFinder.java:107)
	at org.eclipse.jdt.core.dom.SimpleName.subtreeMatch0(SimpleName.java:140)
	at org.eclipse.jdt.core.dom.ASTNode.subtreeMatch(ASTNode.java:2315)
	at org.eclipse.jdt.core.dom.ASTMatcher.safeSubtreeMatch(ASTMatcher.java:138)
	at org.eclipse.jdt.core.dom.ASTMatcher.match(ASTMatcher.java:1386)
	at
org.eclipse.jdt.core.dom.MethodInvocation.subtreeMatch0(MethodInvocation.java:229)
	at org.eclipse.jdt.core.dom.ASTNode.subtreeMatch(ASTNode.java:2315)
	at
org.eclipse.jdt.internal.corext.refactoring.code.SnippetFinder.matches(SnippetFinder.java:204)
	at
org.eclipse.jdt.internal.corext.refactoring.code.SnippetFinder.visitNode(SnippetFinder.java:191)
	at
org.eclipse.jdt.internal.corext.dom.GenericVisitor.visit(GenericVisitor.java:142)
	at org.eclipse.jdt.core.dom.MethodInvocation.accept0(MethodInvocation.java:236)
	at org.eclipse.jdt.core.dom.ASTNode.accept(ASTNode.java:2450)
	at org.eclipse.jdt.core.dom.ASTNode.acceptChild(ASTNode.java:2497)
	at
org.eclipse.jdt.core.dom.VariableDeclarationFragment.accept0(VariableDeclarationFragment.java:224)
	at org.eclipse.jdt.core.dom.ASTNode.accept(ASTNode.java:2450)
	at org.eclipse.jdt.core.dom.ASTNode.acceptChildren(ASTNode.java:2520)
	at
org.eclipse.jdt.core.dom.VariableDeclarationStatement.accept0(VariableDeclarationStatement.java:272)
	at org.eclipse.jdt.core.dom.ASTNode.accept(ASTNode.java:2450)
	at org.eclipse.jdt.core.dom.ASTNode.acceptChildren(ASTNode.java:2520)
	at org.eclipse.jdt.core.dom.Block.accept0(Block.java:135)
	at org.eclipse.jdt.core.dom.ASTNode.accept(ASTNode.java:2450)
	at org.eclipse.jdt.core.dom.ASTNode.acceptChild(ASTNode.java:2497)
	at org.eclipse.jdt.core.dom.IfStatement.accept0(IfStatement.java:189)
	at org.eclipse.jdt.core.dom.ASTNode.accept(ASTNode.java:2450)
	at org.eclipse.jdt.core.dom.ASTNode.acceptChildren(ASTNode.java:2520)
	at org.eclipse.jdt.core.dom.Block.accept0(Block.java:135)
	at org.eclipse.jdt.core.dom.ASTNode.accept(ASTNode.java:2450)
	at org.eclipse.jdt.core.dom.ASTNode.acceptChild(ASTNode.java:2497)
	at org.eclipse.jdt.core.dom.IfStatement.accept0(IfStatement.java:189)
	at org.eclipse.jdt.core.dom.ASTNode.accept(ASTNode.java:2450)
	at org.eclipse.jdt.core.dom.ASTNode.acceptChildren(ASTNode.java:2520)
	at org.eclipse.jdt.core.dom.Block.accept0(Block.java:135)
	at org.eclipse.jdt.core.dom.ASTNode.accept(ASTNode.java:2450)
	at org.eclipse.jdt.core.dom.ASTNode.acceptChild(ASTNode.java:2497)
	at org.eclipse.jdt.core.dom.MethodDeclaration.accept0(MethodDeclaration.java:501)
	at org.eclipse.jdt.core.dom.ASTNode.accept(ASTNode.java:2450)
	at org.eclipse.jdt.core.dom.ASTNode.acceptChildren(ASTNode.java:2520)
	at org.eclipse.jdt.core.dom.TypeDeclaration.accept0(TypeDeclaration.java:483)
	at org.eclipse.jdt.core.dom.ASTNode.accept(ASTNode.java:2450)
	at
org.eclipse.jdt.internal.corext.refactoring.code.SnippetFinder.perform(SnippetFinder.java:138)
	at
org.eclipse.jdt.internal.corext.refactoring.code.ExtractMethodRefactoring.initializeDuplicates(ExtractMethodRefactoring.java:581)
	at
org.eclipse.jdt.internal.corext.refactoring.code.ExtractMethodRefactoring.checkInitialConditions(ExtractMethodRefactoring.java:247)
	at
org.eclipse.ltk.core.refactoring.CheckConditionsOperation.run(CheckConditionsOperation.java:82)
	at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:1719)
	at
org.eclipse.ltk.internal.ui.refactoring.WorkbenchRunnableAdapter.run(WorkbenchRunnableAdapter.java:86)
	at
org.eclipse.jface.operation.ModalContext$ModalContextThread.run(ModalContext.java:113)
Comment 1 Dani Megert CLA 2005-06-28 03:43:58 EDT
In SnippetFinder.java line 107 we call
Bindings.equals(IVariableBinding.getType(), p1) which causes an NPE because
IVariableBinding.getType() returns null which is against the spec.
Comment 2 Philipe Mulet CLA 2005-06-28 05:14:09 EDT
Thanks for investigating Dani.

Olivier - pls comment
Comment 3 Olivier Thomann CLA 2005-06-28 09:46:51 EDT
I will investigate. Thanks Dani.
Comment 4 Olivier Thomann CLA 2005-06-28 09:48:20 EDT
Could you please try to provide an example where this occurs?
Do you have errors in your code?
Comment 5 Khaled Agrama CLA 2005-06-29 11:35:10 EDT
Unfortunately I could not reproduce this problem.  You are correct, the class I
was trying to perform this operation in had errors.  However, the particular
method I was trying to extract from did not have errors...
Comment 6 Olivier Thomann CLA 2005-06-29 11:44:03 EDT
I could reproduce a null type for a variable binding using this code:

public class X {
	void foo(boolean b) {
		Zork z = null;
		if (b) {
			System.out.println(z);
		}
	}
}

However I could not reproduce the NPE. If getType() is used, it will lead to a
NPE. So we need to fix this.
The only way I can see is to return null for the binding of the local. We don't
have support for problem binding within the DOM binding.
Would this be fine for you Dani?
Comment 7 Olivier Thomann CLA 2005-06-29 19:53:45 EDT
When a local variable binding (compiler side) has no type (type == null), we
should not create a VariableBinding (DOM side), otherwise it won't work to
return the getType() and also it won't be possible to get the correspoding java
element.
So in this case the fix is to return no variable binding for a local that has no
valid return type.
Comment 8 Olivier Thomann CLA 2005-06-30 10:35:41 EDT
Dirk and Martin,

Would you be fine if no binding is returned for such boggus local variable. null
is not specified as a possible value for getType(). Therefore the only way I see
to fix this issue is to return no binding at all.
It is spec'd that no binding could be returned in case it is not possible to get
them.
Comment 9 Martin Aeschlimann CLA 2005-06-30 10:50:46 EDT
I assume 'Zork' in your code can't be resolved.

IVariableBinding.getType can't be null, this would be against the spec and would
require us to guard all our code against that.
I guess the correct solution would be that no variable binding is created and
returned at all, but of course we're always happy the more information we get.
What about return 'Object' as return type? Markus, Dirk?


Comment 10 Olivier Thomann CLA 2005-06-30 10:53:15 EDT
I don't like the solution to return Object as this could be misleading. Right
now when bindings are returned, the information is accurate. null looks more
appropriate for me.
Comment 11 Markus Keller CLA 2005-06-30 11:20:06 EDT
IMO, the "no variable binding" vs. "return Object as type" goes along the same
line as bug 84585. I wouldn't object to get a variable with type Object in this
case, iff I'm in "fuzzy" mode.

To reproduce the NPE, simply duplicate the line
			System.out.println(z);
and then try to extract a method out of a reference to "z".
Comment 12 Olivier Thomann CLA 2005-06-30 11:24:53 EDT
Agreed that returning Object is in the same line than bug 84585. But in this
case it should be fixed as part of bug 84585, which means this needs to be
documented.
The problem here is the NPE. And without changing the specs, null seems to be
the only option, doesn't it?
Comment 13 Martin Aeschlimann CLA 2005-06-30 11:46:58 EDT
Returning 'null' would break the spec. All other APIs that return null also spec
this. 'getType()' doesn't, that's why we don't do a null check when we use it.
Comment 14 Olivier Thomann CLA 2005-06-30 11:50:16 EDT
I am not saying returning null to getType(), but returning null as the binding.
This variable would not have any binding, instead of an incomplete binding.
Comment 15 Markus Keller CLA 2005-06-30 11:53:36 EDT
Yes, I think returning no variable binding is the right solution for 3.1.1.
Comment 16 Olivier Thomann CLA 2005-06-30 12:56:59 EDT
Ok, I will return no binding in this case for 3.1.1 and it might be revisited
for 3.2 regarding bug 84585.
Comment 17 Olivier Thomann CLA 2005-06-30 17:08:35 EDT
Fixed and resolved in 3.1 maintenance stream.
Regression test added in
org.eclipse.jdt.core.tests.dom.ASTConverterTestAST3_2.test0613.
Comment 18 Jerome Lanneluc CLA 2005-08-09 08:38:33 EDT
Verified with 3.2 M1
Comment 19 Maxime Daniel CLA 2005-09-26 12:16:19 EDT
Verified for 3.1.1 using build M20050923-1430.
Comment 20 Olivier Thomann CLA 2005-09-26 12:18:03 EDT
Verified.