Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 312867 - [extract method] NPE when trying to "Extract Method"
Summary: [extract method] NPE when trying to "Extract Method"
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: UI (show other bugs)
Version: 3.6   Edit
Hardware: All All
: P3 major (vote)
Target Milestone: 3.6 RC2   Edit
Assignee: Markus Keller CLA
QA Contact:
URL:
Whiteboard:
Keywords:
: 313308 (view as bug list)
Depends on:
Blocks:
 
Reported: 2010-05-14 03:52 EDT by Udo Walker CLA
Modified: 2010-05-19 03:44 EDT (History)
3 users (show)

See Also:
daniel_megert: review+
Olivier_Thomann: review+


Attachments
Proposed fix (1.52 KB, patch)
2010-05-14 08:46 EDT, Olivier Thomann CLA
no flags Details | Diff
fix with test (4.30 KB, patch)
2010-05-18 09:41 EDT, Markus Keller CLA
daniel_megert: review+
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Udo Walker CLA 2010-05-14 03:52:18 EDT
Build Identifier: I20100312-1448

eclipse.buildId=I20100312-1448
java.version=1.6.0_18
java.vendor=Sun Microsystems Inc.
BootLoader constants: OS=win32, ARCH=x86, WS=win32, NL=de_DE
Command-line arguments:  -os win32 -ws win32 -arch x86


Error
Fri May 14 09:44:30 GMT+01:00 2010
Internal Error

java.lang.reflect.InvocationTargetException
	at org.eclipse.jface.operation.ModalContext.run(ModalContext.java:421)
	at org.eclipse.ltk.internal.ui.refactoring.RefactoringWizardDialog2.run(RefactoringWizardDialog2.java:330)
	at org.eclipse.ltk.ui.refactoring.RefactoringWizard.createChange(RefactoringWizard.java:599)
	at org.eclipse.ltk.ui.refactoring.RefactoringWizard.computeUserInputSuccessorPage(RefactoringWizard.java:438)
	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:495)
	at org.eclipse.ltk.internal.ui.refactoring.RefactoringWizardDialog2.access$2(RefactoringWizardDialog2.java:492)
	at org.eclipse.ltk.internal.ui.refactoring.RefactoringWizardDialog2$1.widgetSelected(RefactoringWizardDialog2.java:691)
	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:1050)
	at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:4037)
	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3628)
	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:180)
	at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:70)
	at org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation.run(RefactoringWizardOpenOperation.java:192)
	at org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation.run(RefactoringWizardOpenOperation.java:115)
	at org.eclipse.jdt.internal.ui.refactoring.actions.RefactoringStarter.activate(RefactoringStarter.java:38)
	at org.eclipse.jdt.ui.actions.ExtractMethodAction.run(ExtractMethodAction.java:87)
	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.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:411)
	at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1050)
	at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:4037)
	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3628)
	at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2416)
	at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2380)
	at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2229)
	at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:504)
	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
	at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:497)
	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:619)
	at org.eclipse.equinox.launcher.Main.basicRun(Main.java:574)
	at org.eclipse.equinox.launcher.Main.run(Main.java:1406)
Caused by: java.lang.NullPointerException
	at org.eclipse.jdt.internal.corext.refactoring.util.SelectionAwareSourceRangeComputer.initializeRanges(SelectionAwareSourceRangeComputer.java:94)
	at org.eclipse.jdt.internal.corext.refactoring.util.SelectionAwareSourceRangeComputer.computeSourceRange(SelectionAwareSourceRangeComputer.java:47)
	at org.eclipse.jdt.internal.core.dom.rewrite.RewriteEventStore$NodeRangeInfo.updatePlaceholderSourceRanges(RewriteEventStore.java:189)
	at org.eclipse.jdt.internal.core.dom.rewrite.RewriteEventStore.processListWithRanges(RewriteEventStore.java:756)
	at org.eclipse.jdt.internal.core.dom.rewrite.RewriteEventStore.prepareNodeRangeCopies(RewriteEventStore.java:737)
	at org.eclipse.jdt.internal.core.dom.rewrite.RewriteEventStore.prepareMovedNodes(RewriteEventStore.java:686)
	at org.eclipse.jdt.core.dom.rewrite.ASTRewrite.internalRewriteAST(ASTRewrite.java:268)
	at org.eclipse.jdt.core.dom.rewrite.ASTRewrite.rewriteAST(ASTRewrite.java:260)
	at org.eclipse.jdt.internal.corext.refactoring.code.ExtractMethodRefactoring.createChange(ExtractMethodRefactoring.java:531)
	at org.eclipse.ltk.core.refactoring.CreateChangeOperation.run(CreateChangeOperation.java:124)
	at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:1975)
	at org.eclipse.ltk.internal.ui.refactoring.WorkbenchRunnableAdapter.run(WorkbenchRunnableAdapter.java:87)
	at org.eclipse.jface.operation.ModalContext$ModalContextThread.run(ModalContext.java:121)



Reproducible: Always

Steps to Reproduce:
1.I want to extract a method from following code snippet:
try {
 String absoluteFileName = file.getAbsolutePath();
 String urlEncodedFileName = URLEncoder.encode(absoluteFileName, "UTF-8"); //$NON-NLS-1$
 URL url = new URL("file://" + urlEncodedFileName); //$NON-NLS-1$
 ResourceLocatorTool.addResourceLocator(ResourceLocatorTool.TYPE_TEXTURE, new SimpleResourceLocator(url));
 exporter.save(spatial, file);
 return true;
} catch (IOException e) {
...

I wanted to extract line 2-4 (inclusive) to an extra method an I got the exception.
Comment 1 Olivier Thomann CLA 2010-05-14 08:24:45 EDT
Could you please provide the whole compilation unit code?
Thanks.
Comment 2 Olivier Thomann CLA 2010-05-14 08:45:56 EDT
Reproduced with the following code snippet:

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.net.URLEncoder;

public class Test312867 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		try {
			File file = new File(args[0]);
			String absoluteFileName = file.getAbsolutePath();
			String urlEncodedFileName = URLEncoder.encode(absoluteFileName, "UTF-8"); //$NON-NLS-1$
			URL url = new URL("file://" + urlEncodedFileName); //$NON-NLS-1$
			System.out.println(url);
		} catch (IOException e) {
		}
	}

}

Try to extract a method by selecting the three lines:
			String absoluteFileName = file.getAbsolutePath();
			String urlEncodedFileName = URLEncoder.encode(absoluteFileName, "UTF-8"); //$NON-NLS-1$
			URL url = new URL("file://" + urlEncodedFileName); //$NON-NLS-1$

You need to have a comment line in the selection to see the problem.

fDocumentPortionToScan is set to null on line 71, but it is used when comment line token is found.
Comment 3 Olivier Thomann CLA 2010-05-14 08:46:38 EDT
Created attachment 168530 [details]
Proposed fix

It can either be fixed that way or set the field to null only once it is not used anymore.
Comment 4 Olivier Thomann CLA 2010-05-14 08:46:58 EDT
Moving to JDT/UI
Comment 5 Dani Megert CLA 2010-05-17 10:36:26 EDT
Must fix for 3.6. Regression introduced by bad fix for bug 303313.
Comment 6 Dani Megert CLA 2010-05-18 09:20:14 EDT
*** Bug 313308 has been marked as a duplicate of this bug. ***
Comment 7 Markus Keller CLA 2010-05-18 09:41:23 EDT
Created attachment 168926 [details]
fix with test

Fix with regression test (same fix as proposed by Olivier, but variable doesn't need to be final).
Comment 8 Markus Keller CLA 2010-05-18 09:45:01 EDT
Dani and Olivier, OK for RC2?
Comment 9 Dani Megert CLA 2010-05-18 10:15:28 EDT
+1 for RC2.
Comment 10 Olivier Thomann CLA 2010-05-18 10:56:34 EDT
+1 for RC2
Comment 11 Markus Keller CLA 2010-05-18 13:08:05 EDT
Released to HEAD.
Comment 12 Dani Megert CLA 2010-05-19 03:44:07 EDT
Verified in N20100518-2000.