Community
Participate
Working Groups
I got an error when I selecting it in package explorer. java.lang.IllegalStateException: Mismatching number of parameter annotations, 2>1 in a(Ljava/util/function/Function;Ljava/lang/Object;J)Z in = at org.eclipse.jdt.internal.compiler.classfmt.MethodInfoWithParameterAnnotations.getParameterAnnotations(MethodInfoWithParameterAnnotations.java:46) at org.eclipse.jdt.internal.core.ClassFileInfo.generateMethodInfos(ClassFileInfo.java:364) at org.eclipse.jdt.internal.core.ClassFileInfo.readBinaryChildren(ClassFileInfo.java:432) at org.eclipse.jdt.internal.core.ClassFile.buildStructure(ClassFile.java:91) at org.eclipse.jdt.internal.core.Openable.generateInfos(Openable.java:268) at org.eclipse.jdt.internal.core.JavaElement.openWhenClosed(JavaElement.java:596) at org.eclipse.jdt.internal.core.JavaElement.getElementInfo(JavaElement.java:326) at org.eclipse.jdt.internal.core.JavaElement.getElementInfo(JavaElement.java:312) at org.eclipse.jdt.internal.core.Openable.getBuffer(Openable.java:298) at org.eclipse.jdt.internal.core.AbstractClassFile.getBuffer(AbstractClassFile.java:221) at org.eclipse.jdt.internal.core.AbstractClassFile.getSourceRange(AbstractClassFile.java:347) at org.eclipse.jdt.internal.ui.javaeditor.EditorUtility.getEditorID(EditorUtility.java:424) at org.eclipse.jdt.internal.ui.javaeditor.EditorUtility.openInEditor(EditorUtility.java:182) at org.eclipse.jdt.ui.actions.OpenAction.run(OpenAction.java:287) at org.eclipse.jdt.ui.actions.OpenAction.run(OpenAction.java:252) at org.eclipse.jdt.ui.actions.SelectionDispatchAction.dispatchRun(SelectionDispatchAction.java:274) at org.eclipse.jdt.ui.actions.SelectionDispatchAction.run(SelectionDispatchAction.java:252) at org.eclipse.jdt.internal.ui.packageview.PackageExplorerActionGroup.handleOpen(PackageExplorerActionGroup.java:382) at org.eclipse.jdt.internal.ui.packageview.PackageExplorerPart$4.open(PackageExplorerPart.java:545) at org.eclipse.ui.OpenAndLinkWithEditorHelper$InternalListener.open(OpenAndLinkWithEditorHelper.java:49) at org.eclipse.jface.viewers.StructuredViewer$2.run(StructuredViewer.java:853) at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45) at org.eclipse.ui.internal.JFaceUtil.lambda$0(JFaceUtil.java:47) at org.eclipse.jface.util.SafeRunnable.run(SafeRunnable.java:176) at org.eclipse.jface.viewers.StructuredViewer.fireOpen(StructuredViewer.java:850) at org.eclipse.jface.viewers.StructuredViewer.handleOpen(StructuredViewer.java:1165) at org.eclipse.jface.util.OpenStrategy.fireOpenEvent(OpenStrategy.java:276) at org.eclipse.jface.util.OpenStrategy.access$2(OpenStrategy.java:271) at org.eclipse.jface.util.OpenStrategy$1.handleEvent(OpenStrategy.java:311) at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:89) at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4131) at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1055) at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:3944) at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3547) at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1173) at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:339) at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1062) at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:156) at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:636) at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:339) at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:563) at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:151) at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:155) at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:203) at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:137) at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:107) at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:400) at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:255) 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:498) at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:659) at org.eclipse.equinox.launcher.Main.basicRun(Main.java:595) at org.eclipse.equinox.launcher.Main.run(Main.java:1501) Caused by: java.lang.ArrayIndexOutOfBoundsException: 2 at org.eclipse.jdt.internal.compiler.classfmt.MethodInfoWithParameterAnnotations.getParameterAnnotations(MethodInfoWithParameterAnnotations.java:30) ... 54 more
Larry, I assume this happens only with one file? If yes, could you attach it? If not, which Eclipse version do you have?
Created attachment 277943 [details] e.class
(In reply to Andrey Loskutov from comment #1) > Larry, I assume this happens only with one file? If yes, could you attach > it? If not, which Eclipse version do you have? 4.10 and 4.11 are same, see attachment.
Larry, who has generated e.class? It looks like it reports only 2 parameters but the signature shows 3: // access flags 0xA private static a(Ljava/util/function/Function;Ljava/lang/Object;J)Z // annotable parameter count: 2 (invisible) @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 1 The similar code below shows this bytecode: // access flags 0xA private static a(Ljava/util/function/Function;Ljava/lang/Object;J)Z // annotable parameter count: 3 (invisible) @LNotNull;() // invisible, parameter 1 If we remove the "long" parameter, we will get: // access flags 0xA private static a(Ljava/util/function/Function;Ljava/lang/Object;)Z // annotable parameter count: 2 (invisible) @LNotNull;() // invisible, parameter 1 So for me this looks like an error in the obfuscator who generated e.class, which doesn't properly record parameters count for annotations. This is exact what Stephan commented on bug 474081 comment 1. Below similar code trying to match the related part of the broken class file. ----------------------------------------------------------- import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.util.function.Function; public class X { private static boolean a(Function f, @NotNull Object o, long l) { return false; } } @Documented @Retention(RetentionPolicy.CLASS) @Target({ElementType.FIELD,ElementType.METHOD,ElementType.PARAMETER,ElementType.LOCAL_VARIABLE}) @interface NotNull { }
(In reply to Andrey Loskutov from comment #4) > Larry, who has generated e.class? It looks like it reports only 2 parameters Yes, exactly, this class generated by an obfuscator. I don't know who is. In fact this file is part of IDEA, Maybe nobody might call this method, but it works fine. This file parsed well in Structure of IDEA. In eclipse, package explorer, outline, debug view and so on couldn’t work. So can eclipse ignore this error method?
Thanks larry and Andrey for details and analysis. So the detailed error message from bug 474081 indeed helps to identify the offending method. It can be confirmed that the class file violates JVMS. Ergo the bug should primarily be reported against the tool that created the class file. I'm closing this bug as WORKSFORME. If anyone feels inclined to provide a clean workaround on JDT side, I will tentatively welcome this, but in that case my expectation would be: the illegal class file must be reported in some suitable why rather than silently be swallowed. The code location that currently raises the exception does not have enough context to raise a regular compile error, so it would be tricky to say the least to find a way how to turn the exception into a normal compile error.
(In reply to Stephan Herrmann from comment #6) > Thanks larry and Andrey for details and analysis. So the detailed error > message from bug 474081 indeed helps to identify the offending method. It > can be confirmed that the class file violates JVMS. Ergo the bug should > primarily be reported against the tool that created the class file. > > I'm closing this bug as WORKSFORME. > > If anyone feels inclined to provide a clean workaround on JDT side, I will > tentatively welcome this, but in that case my expectation would be: the > illegal class file must be reported in some suitable why rather than > silently be swallowed. The code location that currently raises the exception > does not have enough context to raise a regular compile error, so it would > be tricky to say the least to find a way how to turn the exception into a > normal compile error. This class can be reflected, so it is a LEGAL class file and NOT violates JVMS.
This class can be reflected, so it is a LEGAL class file and NOT violates JVMS.
(In reply to larry from comment #8) > This class can be reflected, so it is a LEGAL class file and NOT violates > JVMS. Not sure what do you mean by reflected, but the bytecode of this class violates specs. @Stephan, I have a patch that will avoid error dialogs and only report errors to the log and also will show the "error" editor part. I will push it in a second.
(In reply to larry from comment #8) > This class can be reflected, so it is a LEGAL class file and NOT violates > JVMS. This is unsound reasoning. To prove that the class is legal you'd have to argue how it conforms to the following from JVMS (§4.7.18/19): "The value of the num_parameters item gives the number of formal parameters of the method represented by the method_info structure on which the annotation occurs. This duplicates information that could be extracted from the method descriptor." Interestingly, the last sentence was changed in version 10: There is no assurance that this number is the same as the number of parameter descriptors in the method descriptor.
(In reply to Andrey Loskutov from comment #9) > (In reply to larry from comment #8) > > This class can be reflected, so it is a LEGAL class file and NOT violates > > JVMS. > > Not sure what do you mean by reflected, but the bytecode of this class > violates specs. > > @Stephan, I have a patch that will avoid error dialogs and only report > errors to the log and also will show the "error" editor part. I will push it > in a second. This class can load by Class.forName(). I can call getDeclaredMethods(). It seems that JVM thought is a legal class.
(In reply to Stephan Herrmann from comment #10) > Interestingly, the last sentence was changed in version 10: > > There is no assurance that this number is the same as the number of > parameter descriptors in the method descriptor. Does it mean, we should be able to parse this class file now?
Apparently, the spec change was driven by https://bugs.openjdk.java.net/browse/JDK-8067975 (which has several links to related bugs). I'm not a aware of any JSR/JEP that covers this. In particular the comment "However, javac has never emitted Runtime[In]VisibleParameterAnnotations attributes that follow the method descriptor." seems to indicate that they silently adjusted the spec to javac's behavior. This style of changing the spec underfoot is dangerous for any effort to keep ecj in line with the spec. Anyway, the solution to the bug at hand is given further down in latest JVMS (12): "The i'th entry in the parameter_annotations table may, but is not required to, correspond to the i'th parameter descriptor in the method descriptor (§4.3.3). For example, a compiler may choose to create entries in the table corresponding only to those parameter descriptors which represent explicitly declared parameters in source code. In the Java programming language, a constructor of an inner class is specified to have an implicitly declared parameter before its explicitly declared parameters (JLS §8.8.1), so the corresponding <init> method in a class file has a parameter descriptor representing the implicitly declared parameter before any parameter descriptors representing explicitly declared parameters. If the first explicitly declared parameter is annotated in source code, then a compiler may create parameter_annotations[0] to store annotations corresponding to the second parameter descriptor." This needs to be implemented in ecj.
(In reply to larry from comment #11) > It seems that JVM thought is a legal class. Also JVM is just a piece of software which may have bugs. (In reply to Andrey Loskutov from comment #12) > Does it mean, we should be able to parse this class file now? Yep, that's how I read the latest JVMS.
Bulk move to 4.14
Bulk move out of 4.13
A year has passed, how about this?
(In reply to larry from comment #17) > A year has passed, how about this? https://wiki.eclipse.org/Platform/How_to_Contribute ?
It looks like you can have less parameter annotations than the number of parameters. Instead of adding lots of check, we could simply handle the AIOOBE by returning null which would be equivalent to no annotation on the last parameters.
I will prepare a patch for this one.
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.