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

Bug 464655

Summary: Recommenders 2.1.x does not support Eclipse Juno due to int constant inlining at compile time
Product: z_Archived Reporter: EPP Error Reports <error-reports-inbox>
Component: RecommendersAssignee: Marcel Bruch <marcel.bruch>
Status: RESOLVED FIXED QA Contact:
Severity: normal    
Priority: P3 CC: daniel_megert, marcel.bruch, sebastian.zarnekow, sewe
Version: unspecified   
Target Milestone: ---   
Hardware: All   
OS: All   
See Also: https://git.eclipse.org/r/#/c/45836/
Whiteboard:

Description EPP Error Reports CLA 2015-04-15 02:02:11 EDT
The following incident was reported via the automated error reporting:


    code:                   0
    plugin:                 org.eclipse.ui_3.104.0.v20121024-145224
    message:                Unhandled event loop exception
    fingerprint:            bc7ac7f7
    exception class:        java.lang.IllegalArgumentException
    exception message:      -
    number of children:     0
    
    java.lang.IllegalArgumentException: null
    at org.eclipse.jdt.core.dom.ASTParser.<init>(ASTParser.java:226)
    at org.eclipse.jdt.core.dom.ASTParser.newParser(ASTParser.java:125)
    at org.eclipse.recommenders.completion.rcp.processable.ProcessableLazyGenericTypeProposal.getExpectedType(ProcessableLazyGenericTypeProposal.java:657)
    at org.eclipse.recommenders.completion.rcp.processable.ProcessableLazyGenericTypeProposal.computeTypeArgumentProposals(ProcessableLazyGenericTypeProposal.java:348)
    at org.eclipse.recommenders.completion.rcp.processable.ProcessableLazyGenericTypeProposal.computeContextInformation(ProcessableLazyGenericTypeProposal.java:859)
    at org.eclipse.jdt.internal.ui.text.java.LazyJavaCompletionProposal.getContextInformation(LazyJavaCompletionProposal.java:213)
    at org.eclipse.jface.text.contentassist.CompletionProposalPopup.insertProposal(CompletionProposalPopup.java:955)
    at org.eclipse.jface.text.contentassist.CompletionProposalPopup.verifyKey(CompletionProposalPopup.java:1339)
    at org.eclipse.jface.text.contentassist.ContentAssistant$InternalListener.verifyKey(ContentAssistant.java:808)
    at org.eclipse.jface.text.TextViewer$VerifyKeyListenersManager.verifyKey(TextViewer.java:491)
    at org.eclipse.swt.custom.StyledTextListener.handleEvent(StyledTextListener.java:65)
    at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
    at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1053)
    at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1077)
    at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1062)
    at org.eclipse.swt.widgets.Widget.notifyListeners(Widget.java:774)
    at org.eclipse.swt.custom.StyledText.handleKeyDown(StyledText.java:5932)
    at org.eclipse.swt.custom.StyledText$7.handleEvent(StyledText.java:5629)
    at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
    at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1053)
    at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1077)
    at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1062)
    at org.eclipse.swt.widgets.Widget.sendKeyEvent(Widget.java:1104)
    at org.eclipse.swt.widgets.Widget.sendKeyEvent(Widget.java:1100)
    at org.eclipse.swt.widgets.Widget.wmChar(Widget.java:1521)
    at org.eclipse.swt.widgets.Control.WM_CHAR(Control.java:4640)
    at org.eclipse.swt.widgets.Canvas.WM_CHAR(Canvas.java:345)
    at org.eclipse.swt.widgets.Control.windowProc(Control.java:4528)
    at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:341)
    at org.eclipse.swt.widgets.Display.windowProc(Display.java:4976)
    at org.eclipse.swt.internal.win32.OS.DispatchMessageW(OS.java:-2)
    at org.eclipse.swt.internal.win32.OS.DispatchMessage(OS.java:2546)
    at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3756)
    at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$9.run(PartRenderingEngine.java:1053)
    at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
    at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:942)
    at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:86)
    at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:588)
    at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
    at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:543)
    at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
    at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:124)
    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:353)
    at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:180)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(NativeMethodAccessorImpl.java:-2)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:629)
    at org.eclipse.equinox.launcher.Main.basicRun(Main.java:584)
    at org.eclipse.equinox.launcher.Main.run(Main.java:1438)
   
  

General Information:

    reported-by:      
    anonymous-id:     aa098a15-c41d-49c0-8f1d-74c75e0b1035
    eclipse-build-id: M20130204-1200
    eclipse-product:  adtproduct
    operating system: Windows8 6.2.0 (x86_64) - win32
    jre-version:      1.7.0_45-b18

The following plug-ins were present on the execution stack (*):
    1. org.eclipse.core.databinding.observable_1.4.1.v20120521-2329
    2. org.eclipse.core.databinding_1.4.1.v20120912-132807
    3. org.eclipse.core.runtime_3.8.0.v20120912-155025
    4. org.eclipse.e4.ui.workbench_0.11.0.v20130125-100758
    5. org.eclipse.e4.ui.workbench.swt_0.10.3.v20130124-133900
    6. org.eclipse.equinox.app_1.3.100.v20120522-1841
    7. org.eclipse.equinox.launcher_1.3.0.v20120522-1813
    8. org.eclipse.jdt.core_3.8.3.v20130121-145325
    9. org.eclipse.jdt_3.8.1.v201302041200
    10. org.eclipse.jdt.ui_3.8.2.v20130107-165834
    11. org.eclipse.jface.text_3.8.2.v20121126-164145
    12. org.eclipse.jface_3.8.102.v20130123-162658
    13. org.eclipse.recommenders.completion.rcp_2.1.13.v20150323-0859
    14. org.eclipse.swt_3.100.1.v4236b
    15. org.eclipse.ui_3.104.0.v20121024-145224
    16. org.eclipse.ui.ide.application_1.0.400.v20120523-1955
    17. org.eclipse.ui.ide_3.8.2.v20121106-165923

Please note that:
* Messages, stacktraces, and nested status objects may be shortened.
* Bug fields like status, resolution, and whiteboard are sent
  back to reporters.
* The list of present bundles and their respective versions was
  calculated by package naming heuristics. This may or may not reflect reality.

Other Resources:
* Report: https://dev.eclipse.org/recommenders/committers/confess/#/problems/552d4dbce4b026254ee04362  
* Manual: https://dev.eclipse.org/recommenders/community/confess/#/guide


Thank you for your assistance.
Your friendly error-reports-inbox.
Comment 1 Marcel Bruch CLA 2015-04-15 02:14:48 EDT
The constructor is:


ASTParser(int level) {
 switch(level) {
  case AST.JLS2_INTERNAL:
  case AST.JLS3_INTERNAL:
  case AST.JLS4_INTERNAL:
  case AST.JLS8:
   break;
  default:
   throw new IllegalArgumentException(); // here we receive the IAE
 }
 this.apiLevel = level;
 initializeDefaults();
}


We call it with

ASTParser parser = ASTParser.newParser(ASTProvider.SHARED_AST_LEVEL);

which maps to

public static final int SHARED_AST_LEVEL= AST.JLS8;

in Mars / Kepler.


Since it's an int constant: 
We compile the update site jars on the Luna target platform at the moment. I'm pretty sure the value of SHARED_AST_LEVEL changed between and Luna and Juno (JDT is in version 3.8.1/2). I assume that the constant gets inlined at compile time and thus points to an invalid AST.JLS (=8 in our code) which does not yet exist in JDT 3.8.


There is not much we can do: Compiling on Juno and distributing a Juno package. Or marking Juno as not being supported. 

Thoughts?
Comment 2 Sebastian Zarnekow CLA 2015-04-15 02:52:15 EDT
(In reply to Marcel Bruch from comment #1)
> The constructor is:
> 
> 
> ASTParser(int level) {
>  switch(level) {
>   case AST.JLS2_INTERNAL:
>   case AST.JLS3_INTERNAL:
>   case AST.JLS4_INTERNAL:
>   case AST.JLS8:
>    break;
>   default:
>    throw new IllegalArgumentException(); // here we receive the IAE
>  }
>  this.apiLevel = level;
>  initializeDefaults();
> }
> 
> 
> We call it with
> 
> ASTParser parser = ASTParser.newParser(ASTProvider.SHARED_AST_LEVEL);
> 
> which maps to
> 
> public static final int SHARED_AST_LEVEL= AST.JLS8;
> 
> in Mars / Kepler.
> 
> 
> Since it's an int constant: 
> We compile the update site jars on the Luna target platform at the moment.
> I'm pretty sure the value of SHARED_AST_LEVEL changed between and Luna and
> Juno (JDT is in version 3.8.1/2). I assume that the constant gets inlined at
> compile time and thus points to an invalid AST.JLS (=8 in our code) which
> does not yet exist in JDT 3.8.
> 
> 
> There is not much we can do: Compiling on Juno and distributing a Juno
> package. Or marking Juno as not being supported. 
> 
> Thoughts?

Eventually a static getter would be nice on ASTProvider, e.g. getDefaultASTLevel(). That wouldn't be inlined in the client's classfile.
A workaround would be to have a routine in your code, e.g. getASTLevel() with

static int getLevel() {
  int[] levels = new int[] { JLS8, JLS4, JLS3 }
  for(int level: levels) {
try {
  ASTParser.newParser(level);
  return level;
} catch(IllegalArgException e} {}
}

static final int BEST_KNOWN_LEVEL = getLevel()
Comment 3 Andreas Sewe CLA 2015-04-15 02:58:50 EDT
(In reply to Sebastian Zarnekow from comment #2)
> (In reply to Marcel Bruch from comment #1)
> > There is not much we can do: Compiling on Juno and distributing a Juno
> > package. Or marking Juno as not being supported. 
> > 
> > Thoughts?
> 
> Eventually a static getter would be nice on ASTProvider, e.g.
> getDefaultASTLevel(). That wouldn't be inlined in the client's classfile.
> A workaround would be to have a routine in your code, e.g. getASTLevel() with
> 
> static int getLevel() {
>   int[] levels = new int[] { JLS8, JLS4, JLS3 }
>   for(int level: levels) {
> try {
>   ASTParser.newParser(level);
>   return level;
> } catch(IllegalArgException e} {}
> }
> 
> static final int BEST_KNOWN_LEVEL = getLevel()

Alternatively, you could use reflection to access the static field in question, which is, IMHO, more explicit than the proposed getLevel() method.

What do you think?
Comment 4 Marcel Bruch CLA 2015-04-15 03:14:03 EDT
Thanks for both options. I stopped thinking about this after the analysis :-)

Since we use reflection in several places already, I think Andreas solution is the way to go (for us) here. We should, however, encapsulate this in a static method somewhere below org.eclipse.recommenders.jdt.

Adding a static method in SharedASTProvider makes sense for future issues. For now we'd need one of the above outlined workarounds. 

Adding Dani for a short comment on whether a contribution that adds such a method to SharedASTProvider would be welcome.
Comment 5 Andreas Sewe CLA 2015-04-17 09:22:07 EDT
(In reply to Marcel Bruch from comment #4)
> Thanks for both options. I stopped thinking about this after the analysis :-)
> 
> Since we use reflection in several places already, I think Andreas solution
> is the way to go (for us) here. We should, however, encapsulate this in a
> static method somewhere below org.eclipse.recommenders.jdt.
> 
> Adding a static method in SharedASTProvider makes sense for future issues.
> For now we'd need one of the above outlined workarounds. 

This has been done and the change has been merged: <https://git.eclipse.org/r/#/c/45836/>.

Closing this issue.
Comment 6 Marcel Bruch CLA 2015-04-18 18:37:53 EDT
*** Bug 464353 has been marked as a duplicate of this bug. ***
Comment 7 Dani Megert CLA 2015-04-21 08:07:31 EDT
(In reply to Marcel Bruch from comment #4)
> Adding a static method in SharedASTProvider makes sense for future issues.
> For now we'd need one of the above outlined workarounds. 
> 
> Adding Dani for a short comment on whether a contribution that adds such a
> method to SharedASTProvider would be welcome.

1. create an AST via shared AST provider
2. yourAST.getAST().apiLevel()