Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 441959

Summary: [quick assist] Exception while processing quick fixes or quick assists
Product: [Eclipse Project] JDT Reporter: Marcel Bruch <marcel.bruch>
Component: CoreAssignee: Jay Arthanareeswaran <jarthana>
Status: CLOSED WONTFIX QA Contact:
Severity: normal    
Priority: P3 CC: jarthana, markus.kell.r, noopur_gupta
Version: 4.5   
Target Milestone: ---   
Hardware: All   
OS: All   
Whiteboard: stalebug

Description Marcel Bruch CLA 2014-08-18 07:38:59 EDT
eclipse.buildId=4.4.0.I20140606-1215
java.version=1.8.0
java.vendor=Oracle Corporation
BootLoader constants: OS=macosx, ARCH=x86_64, WS=cocoa, NL=de_DE
Framework arguments:  -product org.eclipse.epp.package.standard.product -keyring /Users/Marcel/.eclipse_keyring -showlocation
Command-line arguments:  -os macosx -ws cocoa -arch x86_64 -product org.eclipse.epp.package.standard.product -keyring /Users/Marcel/.eclipse_keyring -showlocation

org.eclipse.jdt.ui
Error
Mon Aug 18 13:37:13 CEST 2014
Exception while processing quick fixes or quick assists

java.lang.ClassCastException: org.eclipse.jdt.internal.core.ResolvedSourceMethod cannot be cast to org.eclipse.jdt.core.IType
	at org.eclipse.jdt.internal.ui.text.correction.QuickAssistProcessor.getConvertAnonymousToNestedProposal(QuickAssistProcessor.java:508)
	at org.eclipse.jdt.internal.ui.text.correction.QuickAssistProcessor.getAssists(QuickAssistProcessor.java:282)
	at org.eclipse.jdt.internal.ui.text.correction.JavaCorrectionProcessor$SafeAssistCollector.safeRun(JavaCorrectionProcessor.java:403)
	at org.eclipse.jdt.internal.ui.text.correction.JavaCorrectionProcessor$SafeCorrectionProcessorAccess.run(JavaCorrectionProcessor.java:339)
	at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
	at org.eclipse.jdt.internal.ui.text.correction.JavaCorrectionProcessor$SafeCorrectionProcessorAccess.process(JavaCorrectionProcessor.java:329)
	at org.eclipse.jdt.internal.ui.text.correction.JavaCorrectionProcessor.collectAssists(JavaCorrectionProcessor.java:509)
	at org.eclipse.jdt.internal.ui.text.correction.JavaCorrectionProcessor.collectProposals(JavaCorrectionProcessor.java:287)
	at org.eclipse.jdt.internal.ui.text.correction.JavaCorrectionProcessor.computeQuickAssistProposals(JavaCorrectionProcessor.java:242)
	at org.eclipse.jface.text.quickassist.QuickAssistAssistant$ContentAssistProcessor.computeCompletionProposals(QuickAssistAssistant.java:75)
	at org.eclipse.jface.text.contentassist.ContentAssistant.computeCompletionProposals(ContentAssistant.java:1861)
	at org.eclipse.jface.text.contentassist.CompletionProposalPopup.computeProposals(CompletionProposalPopup.java:573)
	at org.eclipse.jface.text.contentassist.CompletionProposalPopup.access$16(CompletionProposalPopup.java:570)
	at org.eclipse.jface.text.contentassist.CompletionProposalPopup$2.run(CompletionProposalPopup.java:505)
	at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:70)
	at org.eclipse.jface.text.contentassist.CompletionProposalPopup.showProposals(CompletionProposalPopup.java:499)
	at org.eclipse.jface.text.contentassist.ContentAssistant.showPossibleCompletions(ContentAssistant.java:1687)
	at org.eclipse.jface.text.quickassist.QuickAssistAssistant.showPossibleQuickAssists(QuickAssistAssistant.java:128)
	at org.eclipse.jdt.internal.ui.text.correction.JavaCorrectionAssistant.showPossibleQuickAssists(JavaCorrectionAssistant.java:193)
	at org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitEditor$AdaptedSourceViewer.doOperation(CompilationUnitEditor.java:195)
	at org.eclipse.ui.texteditor.TextOperationAction$1.run(TextOperationAction.java:128)
	at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:70)
	at org.eclipse.ui.texteditor.TextOperationAction.run(TextOperationAction.java:126)
	at org.eclipse.jface.action.Action.runWithEvent(Action.java:519)
	at org.eclipse.jface.commands.ActionHandler.execute(ActionHandler.java:122)
	at org.eclipse.ui.internal.handlers.E4HandlerProxy.execute(E4HandlerProxy.java:90)
	at sun.reflect.GeneratedMethodAccessor204.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:483)
	at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:55)
	at org.eclipse.e4.core.internal.di.InjectorImpl.invokeUsingClass(InjectorImpl.java:247)
	at org.eclipse.e4.core.internal.di.InjectorImpl.invoke(InjectorImpl.java:229)
	at org.eclipse.e4.core.contexts.ContextInjectionFactory.invoke(ContextInjectionFactory.java:132)
	at org.eclipse.e4.core.commands.internal.HandlerServiceHandler.execute(HandlerServiceHandler.java:149)
	at org.eclipse.core.commands.Command.executeWithChecks(Command.java:499)
	at org.eclipse.core.commands.ParameterizedCommand.executeWithChecks(ParameterizedCommand.java:508)
	at org.eclipse.e4.core.commands.internal.HandlerServiceImpl.executeHandler(HandlerServiceImpl.java:210)
	at org.eclipse.e4.ui.bindings.keys.KeyBindingDispatcher.executeCommand(KeyBindingDispatcher.java:286)
	at org.eclipse.e4.ui.bindings.keys.KeyBindingDispatcher.press(KeyBindingDispatcher.java:507)
	at org.eclipse.e4.ui.bindings.keys.KeyBindingDispatcher.processKeyEvent(KeyBindingDispatcher.java:558)
	at org.eclipse.e4.ui.bindings.keys.KeyBindingDispatcher.filterKeySequenceBindings(KeyBindingDispatcher.java:378)
	at org.eclipse.e4.ui.bindings.keys.KeyBindingDispatcher.access$0(KeyBindingDispatcher.java:324)
	at org.eclipse.e4.ui.bindings.keys.KeyBindingDispatcher$KeyDownFilter.handleEvent(KeyBindingDispatcher.java:86)
	at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
	at org.eclipse.swt.widgets.Display.filterEvent(Display.java:1087)
	at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4184)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1467)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1490)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1475)
	at org.eclipse.swt.widgets.Widget.sendKeyEvent(Widget.java:1504)
	at org.eclipse.swt.widgets.Widget.sendKeyEvent(Widget.java:1500)
	at org.eclipse.swt.widgets.Canvas.sendKeyEvent(Canvas.java:496)
	at org.eclipse.swt.widgets.Control.doCommandBySelector(Control.java:1060)
	at org.eclipse.swt.widgets.Display.windowProc(Display.java:5719)
	at org.eclipse.swt.internal.cocoa.OS.objc_msgSend(Native Method)
	at org.eclipse.swt.internal.cocoa.NSResponder.interpretKeyEvents(NSResponder.java:68)
	at org.eclipse.swt.widgets.Composite.keyDown(Composite.java:594)
	at org.eclipse.swt.widgets.Display.windowProc(Display.java:5629)
	at org.eclipse.swt.internal.cocoa.OS.objc_msgSendSuper(Native Method)
	at org.eclipse.swt.widgets.Widget.callSuper(Widget.java:221)
	at org.eclipse.swt.widgets.Widget.windowSendEvent(Widget.java:2105)
	at org.eclipse.swt.widgets.Shell.windowSendEvent(Shell.java:2329)
	at org.eclipse.swt.widgets.Display.windowProc(Display.java:5691)
	at org.eclipse.swt.internal.cocoa.OS.objc_msgSendSuper(Native Method)
	at org.eclipse.swt.widgets.Display.applicationSendEvent(Display.java:5128)
	at org.eclipse.swt.widgets.Display.applicationProc(Display.java:5277)
	at org.eclipse.swt.internal.cocoa.OS.objc_msgSend(Native Method)
	at org.eclipse.swt.internal.cocoa.NSApplication.sendEvent(NSApplication.java:128)
	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3655)
	at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$9.run(PartRenderingEngine.java:1151)
	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
	at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1032)
	at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:148)
	at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:636)
	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
	at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:579)
	at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:150)
	at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:135)
	at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:382)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:236)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:483)
	at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:648)
	at org.eclipse.equinox.launcher.Main.basicRun(Main.java:603)
	at org.eclipse.equinox.launcher.Main.run(Main.java:1465)
Comment 1 Marcel Bruch CLA 2014-08-18 07:41:40 EDT
Little more context:


public class myJob extends Job {


    @Override
    protected IStatus run(IProgressMonitor monitor) {
        monitor.beginTask("Analyzing", IProgressMonitor.UNKNOWN);

        if (isModal(this)) {
            new
        } else {
            setProperty(IProgressConstants.KEEP_PROPERTY, Boolean.TRUE);
            setProperty(IProgressConstants.ACTION_PROPERTY, new Acti|<>on() { // <--- press CMD+1 on Action()
                @Override
                public void run() {
                    MessageDialog.openInformation(null, "...", "");
                }
            });
        }
        return Status.OK_STATUS;
    }
Comment 2 Noopur Gupta CLA 2014-08-20 07:12:39 EDT
At QuickAssistProcessor.java:508, the code is:
((IType) anonymTypeBinding.getJavaElement())

With the given example, "anonymTypeBinding" comes as:
Anonymous type : (id=NoId)
final class $Local$
...

However, anonymTypeBinding.getJavaElement() returns a ResolvedSourceMethod:
IStatus run(IProgressMonitor)

which results in CCE.

Moving to JDT/Core for comments on why a ResolvedSourceMethod is returned instead of a ResolvedSourceType for the anonymous type binding.
Comment 3 Jay Arthanareeswaran CLA 2014-08-25 01:27:09 EDT
(In reply to Noopur Gupta from comment #2)
> Moving to JDT/Core for comments on why a ResolvedSourceMethod is returned
> instead of a ResolvedSourceType for the anonymous type binding.

Looks like a bug, I will investigate why it is so.
Comment 4 Jay Arthanareeswaran CLA 2014-08-26 00:22:13 EDT
I can reproduce in master as well as 4.3 and 4.2. The broken code is causing the anonymous types to be not-available and hence getElementAt() returns the enclosing method as the element. We can probably do an instanceof check and avoid the CCE. I don't see what else we can do here.
Comment 5 Markus Keller CLA 2014-08-26 15:31:16 EDT
I'd say the bug is that the Java model doesn't contain the anonymous type, although the AST recovery could come up with a ClassInstanceCreation node.

If there's no way to get the right IType element, then doing a sanity check and returning null would probably be better in this case. But this needs to be documented in the API (as specific as possible -- not just "can return null").
Comment 6 Jay Arthanareeswaran CLA 2014-08-27 01:23:17 EDT
(In reply to Markus Keller from comment #5)
> I'd say the bug is that the Java model doesn't contain the anonymous type,
> although the AST recovery could come up with a ClassInstanceCreation node.

Yep, to add some more details, in case there is a compilation error in the code surrounding the anonymous type, in this case, the if/else statement, the ASTNode.HasLocalType flag is not. But the construction of Java element for the anonymous types depends on this bit being set.
Comment 7 Jay Arthanareeswaran CLA 2014-08-27 04:09:13 EDT
The code and doc changes are here:

https://git.eclipse.org/r/32371

With this, there is at least one NPE on the jdt.ui that should be taken care of. Until then, this can wait.
Comment 8 Markus Keller CLA 2014-09-29 12:17:20 EDT
(In reply to Jayaprakash Arthanareeswaran from comment #7)
The problem with that proposal is that it's still a breaking API change for most clients. The API of IBinding#getJavaElement() guarantees to return non-null except in a few cases that can easily be ruled out by clients. Either by construction (client e.g. knows that the type of an exception always has a Java element), or by explicit tests (e.g. checking the 'synthetic' flag).

The org.eclipse.jdt.ui project alone has 105 references to this method, and if we don't have a simple rule to protect us from NPEs, then we have to make a pass over all these references and add workarounds / error handling for cases where it now can return null. That would be OK for internal code, but not for public APIs.
Comment 9 Eclipse Genie CLA 2019-10-12 11:55:21 EDT
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet.

If you have further information on the current state of the bug, please add it. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant.

--
The automated Eclipse Genie.