Community
Participate
Working Groups
Build Identifier: M20090917-0800 Have a look at ReorgPolicy.canEnable(): public boolean canEnable() throws JavaModelException { IResource[] resources= getResources(); for (int i= 0; i < resources.length; i++) { IResource resource= resources[i]; if (!resource.exists() || resource.isPhantom() || !resource.isAccessible()) return false; } IJavaElement[] javaElements= getJavaElements(); for (int i= 0; i < javaElements.length; i++) { IJavaElement element= javaElements[i]; if (!element.exists()) return false; } return true; } The last "return true" is wrong, as it would enable the policy even if the resources and javaElements arrays are empty. The same problem occurs in many other ReorgPolicy classes. We experience this bug when using an own IQueryParticipant that creates non-IJavaElement matches. I'll attach a patch against HEAD. Reproducible: Always
Created attachment 159997 [details] Fixes the buggy canEnable() methods
BTW, the result of the erroneous canEnable() returns is an ArrayIndexOutOfBoundsException later on, e.g. see this stacktrace: java.lang.ArrayIndexOutOfBoundsException: 0 at org.eclipse.jdt.internal.corext.refactoring.reorg.ReorgPolicyFactory$SubCuElementReorgPolicy.getSourceCu(ReorgPolicyFactory.java:3741) at org.eclipse.jdt.internal.corext.refactoring.reorg.ReorgPolicyFactory$MoveSubCuElementsPolicy.canEnable(ReorgPolicyFactory.java:2077) at org.eclipse.jdt.internal.corext.refactoring.RefactoringAvailabilityTester.isMoveAvailable(RefactoringAvailabilityTester.java:791) at org.eclipse.jdt.internal.ui.refactoring.reorg.ReorgMoveAction.selectionChanged(ReorgMoveAction.java:62) at org.eclipse.jdt.ui.actions.SelectionDispatchAction.dispatchSelectionChanged(SelectionDispatchAction.java:262) at org.eclipse.jdt.ui.actions.SelectionDispatchAction.selectionChanged(SelectionDispatchAction.java:257) at org.eclipse.jdt.ui.actions.MoveAction.selectionChanged(MoveAction.java:116) at org.eclipse.ui.part.PageBookView$5.run(PageBookView.java:256) at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42) at org.eclipse.core.runtime.Platform.run(Platform.java:888) at org.eclipse.ui.part.PageBookView$SelectionManager.selectionChanged(PageBookView.java:254) at org.eclipse.ui.part.PageBookView$SelectionProvider.selectionChanged(PageBookView.java:320) at org.eclipse.ui.part.PageBookView.pageSelectionChanged(PageBookView.java:897) at org.eclipse.ui.part.PageBookView.access$2(PageBookView.java:892) at org.eclipse.ui.part.PageBookView$2.selectionChanged(PageBookView.java:164) at org.eclipse.search.ui.text.AbstractTextSearchViewPage$SelectionProviderAdapter.selectionChanged(AbstractTextSearchViewPage.java:192) at org.eclipse.jface.viewers.Viewer$2.run(Viewer.java:162) at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42) at org.eclipse.core.runtime.Platform.run(Platform.java:888) at org.eclipse.ui.internal.JFaceUtil$1.run(JFaceUtil.java:48) at org.eclipse.jface.util.SafeRunnable.run(SafeRunnable.java:175) at org.eclipse.jface.viewers.Viewer.fireSelectionChanged(Viewer.java:160) at org.eclipse.jface.viewers.StructuredViewer.updateSelection(StructuredViewer.java:2132) at org.eclipse.jface.viewers.StructuredViewer.setSelection(StructuredViewer.java:1669) at org.eclipse.jface.viewers.TreeViewer.setSelection(TreeViewer.java:1124) at org.eclipse.search2.internal.ui.basic.views.TreeViewerNavigator.internalSetSelection(TreeViewerNavigator.java:194) at org.eclipse.search2.internal.ui.basic.views.TreeViewerNavigator.navigateNext(TreeViewerNavigator.java:46) at org.eclipse.search.ui.text.AbstractTextSearchViewPage.navigateNext(AbstractTextSearchViewPage.java:946) at org.eclipse.search.ui.text.AbstractTextSearchViewPage.access$10(AbstractTextSearchViewPage.java:939) at org.eclipse.search.ui.text.AbstractTextSearchViewPage$UpdateUIJob.runInUIThread(AbstractTextSearchViewPage.java:151) at org.eclipse.ui.progress.UIJob$1.run(UIJob.java:95) at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35) at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:134) at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:3468) at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3115) at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2405) at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2369) at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2221) at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:500) at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332) at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:493) 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:194) 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:368) at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179) 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.equinox.launcher.Main.invokeFramework(Main.java:559) at org.eclipse.equinox.launcher.Main.basicRun(Main.java:514) at org.eclipse.equinox.launcher.Main.run(Main.java:1311) at org.eclipse.equinox.launcher.Main.main(Main.java:1287) This is due to // we checked before that the array in not null and not empty return getEnclosingCompilationUnit(fJavaElements[0]); in getSourceCu().
Any comments? This is quite a simple fix.
Makes sense, released to HEAD.
Thanks a bunch, Markus!