Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8356322

javac generates incorrect static init order when interface has default method

XMLWordPrintable

    • generic
    • generic

      ADDITIONAL SYSTEM INFORMATION :
      Linux focus 6.6.88 #1-NixOS SMP PREEMPT_DYNAMIC Fri Apr 25 08:45:59 UTC 2025 x86_64 GNU/Linux

      openjdk version "1.8.0_442"
      OpenJDK Runtime Environment (build 1.8.0_442-06)
      OpenJDK 64-Bit Server VM (build 25.442-b06, mixed mode)


      openjdk 11.0.26 2025-01-21
      OpenJDK Runtime Environment (build 11.0.26+0-adhoc..source)
      OpenJDK 64-Bit Server VM (build 11.0.26+0-adhoc..source, mixed mode)


      openjdk 17.0.14 2025-01-21
      OpenJDK Runtime Environment (build 17.0.14+7-nixos)
      OpenJDK 64-Bit Server VM (build 17.0.14+7-nixos, mixed mode, sharing

      openjdk 21.0.5 2024-10-15
      OpenJDK Runtime Environment (build 21.0.5+1-nixos)
      OpenJDK 64-Bit Server VM (build 21.0.5+1-nixos, mixed mode, sharing)


      openjdk 23.0.1 2024-10-15
      OpenJDK Runtime Environment (nix) (build 23.0.1+11)
      OpenJDK 64-Bit Server VM (nix) (build 23.0.1+11, mixed mode, sharing)


      A DESCRIPTION OF THE PROBLEM :
      javac emits incorrect bytecode when an interface declares a static field that depends on a nested class, and the interface also defines a default method. This causes incorrect static initialization order at runtime, resulting in null values where a valid reference is expected.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      ```
      // File: MyIssue.java
      public interface MyIssue {
          String schema = MyIssue.A.schema;

          // commenting out below method fixes the issue
          default void accept(String var1) {
          }

          final class A implements MyIssue {
              public static final String schema = new String("aa").trim();
          }
      }
      ```
      ```
      // File: Application.java
      public class Application {
          public static void main(String[] args) {
              // Uncommenting this line fixes the issue by triggering MyIssue.<clinit>
              // System.out.println(MyIssue.schema);

              System.out.println(MyIssue.A.schema); // prints "aa"
              System.out.println(MyIssue.schema); // prints "null" (!!)
          }
      }
      ```

      javac -d out Application.java MyIssue.java
      java -cp out Application



      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      execution prints on stdout:
      aa
      aa
      ACTUAL -
      execution prints on stdout:
      aa
      null

        1. Application.java
          0.3 kB
          Andrew Wang
        2. MyIssue.java
          0.3 kB
          Andrew Wang

            Unassigned Unassigned
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: