Details
-
Bug
-
Status: Closed
-
Major
-
Resolution: Fixed
-
None
-
None
-
None
Description
Create a file using a JDK8 static interface method, e.g. MyScript.groovy:
import groovy.transform.CompileStatic
@CompileStatic
Comparator myMethod() {
Map.Entry.comparingByKey()
}
Compile using JDK8. On Groovy 3.0, use -Dgroovy.target.bytecode=1.7 (not required for 2.5/6).
Note from javap -v that the bytecode version is:
major version: 51
and that an InterfaceMethodref to the Map.Entry static interface method exists:
#48 = InterfaceMethodref #45.#47 // java/util/Map$Entry.comparingByKey:()Ljava/util/Comparator;
Now try to use that class in another script, e.g.:
println new MyScript().myMethod()
You will note this error:
java.lang.VerifyError: Illegal type at constant pool entry 48 in class MyScript Exception Details: Location: MyScript.myMethod()Ljava/util/Comparator; @0: invokestatic Reason: Constant pool index 48 is invalid
For Groovy 2.5/6 you can just run groovy MyScript.groovy to see the VerifyError, though using groovyc will let you see the generated bytecode.
So there are two problems:
- we should not set bytecode level to be the minimum level for the Groovy version (7 is default for 2.5/6) when producing bytecode requiring JDK8+.
- we should probably just complain if groovy.target.bytecode is ever set below the minimum value for the particular Groovy version.