-
Bug
-
Resolution: Unresolved
-
Minor
-
None
When running on JDK 14 or newer, Groovy 2.x regresses to using Java 6 bytecode for generated classes rather than Java 8 bytecode as it does when running on JDK 11 to JDK 13. This breaks some language features, in particular static interface methods like List.of. Attempting to call such a method in a Groovy script will throw a VerifyError like the following:
java.lang.VerifyError: (class: java_util_List$of$17, method: call signature: (Ljava/lang/Object;)Ljava/lang/Object;) Illegal type in constant pool
The reason for the change in behavior is that https://github.com/openjdk/jdk/commit/068575e9b11703d67af45bac0944b0d521f69fba, which appears to have first landed in JDK 14, modified the signature of the (private) constructor that Groovy uses to check for JDK 7+ support (see here). Since the JDK 8 support class extends the JDK 7 support class, the JDK 8 support class also fails to load on JDK 14+ (see Java8).
This causes Groovy’s VMPluginFactory.getPlugin to return the Java6 plugin on Java 14+ (see here), which in turn means that classes generated by Groovy use Java 6 bytecode, and that breaks some Java 8 language features like calls to static interface methods.
With JDK 7-13, the signature of the private MethodHandles.Lookup constructor matches what Groovy expects, so Groovy uses Java 8 bytecode.
I think that the earliest fix for this in Groovy is this commit which landed in Groovy 4.x, but perhaps there is an earlier fix as well.
I am not aware of any workaround other than avoiding direct calls to static interface methods from Groovy scripts.
- is blocked by
-
JENKINS-68690 Upgrade Groovy from 3.0.x to 4.0.x
- Open