Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-73031

Groovy 2.x regresses to Java 6 bytecode when running JDK 14+

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: Minor Minor
    • core
    • 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.

          [JENKINS-73031] Groovy 2.x regresses to Java 6 bytecode when running JDK 14+

          Basil Crow added a comment -

          Suggest reviving our dead fork of Groovy to deliver a targeted patch.

          Basil Crow added a comment - Suggest reviving our dead fork of Groovy to deliver a targeted patch.

          This problem occurs when incompatible code is used in:

          • plugins
          • shared libraries

          As a workaround, would it be possible to detect the the specific VerifyError and provide a better explanation, ideally with a link to examples of problematic code and alternatives?

          I think a lot of the problems arise due to lack of transparency of what the problem is. Informing people may raise awareness and avoid additional problems. At least until there is time to solve it properly.

          Steve Boardwell added a comment - This problem occurs when incompatible code is used in: plugins shared libraries As a workaround, would it be possible to detect the the specific VerifyError and provide a better explanation, ideally with a link to examples of problematic code and alternatives? I think a lot of the problems arise due to lack of transparency of what the problem is. Informing people may raise awareness and avoid additional problems. At least until there is time to solve it properly.

          Jesse Glick added a comment -

          Jesse Glick added a comment - Like https://github.com/jenkinsci/workflow-cps-plugin/pull/936 ?

            Unassigned Unassigned
            dnusbaum Devin Nusbaum
            Votes:
            1 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated: