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

REGRESSION: static initialization delayed too long under Java 1.6

    XMLWordPrintable

Details

    • Bug
    • Resolution: Not an Issue
    • P3
    • None
    • 6u14
    • tools
    • x86
    • windows_2003

    Description

      FULL PRODUCT VERSION :
      I:\tmp>"%JAVA6_HOME%\bin\java" -version
      java version "1.6.0_11"
      Java(TM) SE Runtime Environment (build 1.6.0_11-b03)
      Java HotSpot(TM) Client VM (build 11.0-b16, mixed mode, sharing)
      Java SE 6.0 Update 14


      ADDITIONAL OS VERSION INFORMATION :
      I:\tmp>ver

      Microsoft Windows [Version 5.2.3790]

      A DESCRIPTION OF THE PROBLEM :
      Under Java 1.4, the reference B.class in class A's static initialization block was sufficient to cause B's static initialization block to be executed.

      Under Java 1.6, this is no longer true. Note that running 1.6's javac with -source 1.4 -target 1.4 works around this problem.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Compile the 5 source files listed below using 1.6's javac as follows:

      javac *.java

      then run as follows

      java -cp . Main

      Note that the last dump of remembered classes only shows Late and Later.

      Now run using

      java -cp . Main x

      Note that the last dump of remembered classes shows Late, Later and EvenLater. (With an argument, the static initialization block of Later uses Class.forName() to load EvenLater rather than reference EvenLater.class).

      Recompile using

      javac -source 1.4 -target 1.4 *.java

      and run using

      java -cp . Main

      and notice that now the last dump of rememberd classes includes Late, Later and EvenLater.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      I expect that the third and fourth dump of remembered classes shows all three classes (Late, Later and EvenLater). This was the behavior under 1.4.2_13.
      ACTUAL -
      I only see two of the classes dumped (Late and Later).

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      There are five classes: Main, Helper, Late, Later and EvenLater:

      Main.java:
      public class Main {
          public static void main(String[] args) throws Exception {
              if (args.length > 0) {
                  Helper.setUseLoadClass(true);
              }
              System.out.println("Dump 1 of remembered classes: " + Helper.getRemembered());
              Late reference;
              System.out.println("Dump 2 of remembered classes: " + Helper.getRemembered());
              Class classReference = Late.class;
              System.out.println("Dump 3 of remembered classes: " + Helper.getRemembered());
              reference = new Late();
              System.out.println("Dump 4 of remembered classes: " + Helper.getRemembered());
          }
      }

      Helper.java:
      import java.util.*;
      public class Helper {
          private static HashMap remembered = new HashMap();
          private static boolean useLoadClass = false;
          public static HashMap getRemembered() {
              return remembered;
          }
          public static void setUseLoadClass(boolean useLoadClass) {
              Helper.useLoadClass = useLoadClass;
          }
          public static boolean useLoadClass() {
              return useLoadClass;
          }
          public static void remember(String key, Class value) {
              remembered.put(key, value);
          }
          public static Class loadClass(String className) {
              try {
                  return Class.forName(className);
              } catch (ClassNotFoundException exception) {
                  return null;
              }
          }
      }

      Late.java:
      public class Late {
          static {
              Helper.remember("Later", Helper.useLoadClass() ? Helper.loadClass("Later") : Later.class);
              Helper.remember("Late", Late.class);
          }
      }

      Later.java:
      public class Later {
          static {
              Helper.remember("EvenLater", EvenLater.class);
              Helper.remember("Later", Later.class);
          }
      }

      EvenLater.java:
      public class EvenLater {
          static {
              Helper.remember("EvenLater", EvenLater.class);
          }
      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Compile with -source 1.4 -target 1.4. However, this means that we can not use any 1.5 or beyond functionality in a large set of our source files.

      Release Regression From : 1.4
      The above release value was the last known release where this
      bug was not reproducible. Since then there has been a regression.

      Attachments

        Issue Links

          Activity

            People

              Unassigned Unassigned
              ndcosta Nelson Dcosta (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:
                Imported:
                Indexed: