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

ExceptionInInitializerError when accessing non-trivial enum used in a switch

XMLWordPrintable

    • x86_64
    • windows_10

      ADDITIONAL SYSTEM INFORMATION :
      Windows 10, Version 10.0.16299 Build 16299.
      IDE: Oxygen.3a Release (4.7.3a)
      Compiler: JDT for JavaSE-9

      VM info:
      java version "10.0.2" 2018-07-17
      Java(TM) SE Runtime Environment 18.3 (build 10.0.2+13)
      Java HotSpot(TM) 64-Bit Server VM 18.3 (build 10.0.2+13, mixed mode)

      Can be reproduced with Java 9.

      A DESCRIPTION OF THE PROBLEM :
      When
      # an enum type E with a non-default constructor is defined inside a class A, and
      # this class A defines a static final constant C, and
      # an enum value of E uses this constant C for construction, and
      # the class A uses the enum E somewhere in a switch statement (no matter where - even in non-reachable code),
      then accessing the enum E (e.g. one of its values) from another class causes a ExceptionInInitializerError due to a NullPointerException in the values() method of the enum.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      See source code for details.
      (1) write a class A.
      (2) define a constant C inside this class.
      (3) define a enum E inside this class with a one-argument-constructor. The constructor can be empty.
      (4) define an enum value V inside E that uses the constant C for construction.
      (5) add an arbitrary method to the class that uses the enum in a switch statement.
      (6) write another class with a main method and simply access the enum values there (e.g. call A.E.values() );

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      VM terminates normally
      ACTUAL -
      VM terminates with the following error:

      Exception in thread "main" java.lang.ExceptionInInitializerError
      at MyClass$State.<clinit>(SwitchBug.java:12)
      at SwitchBug.main(SwitchBug.java:4)
      Caused by: java.lang.NullPointerException
      at MyClass$State.values(SwitchBug.java:1)
      at MyClass.$SWITCH_TABLE$MyClass$State(SwitchBug.java:8)
      at MyClass.<clinit>(SwitchBug.java:9)
      ... 2 more


      ---------- BEGIN SOURCE ----------
      // --- file SwitchBug.java ---
      public class SwitchBug {
      public static void main(String[] args) {
      // access enum values from an other class
      MyClass.State.values();
      }
      }

      class MyClass {
      private static final Object C = "";

      public enum State {
      ENABLED(C); // pass null constant

      State(Object value) {} // value can be ignored
      }

      /* unused method with switch statement IN SAME CLASS */
      private static void unusedMethod() {
      switch (State.ENABLED) {
      case ENABLED:
      break;
      }
      }
      }
      // --- end of file ---
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Some modifications of the code above can solve the issue:
      # don't use a switch statement in MyClass. (remove the "unusedMethod()").
      # don't use the constant C for enum construction (e.g. use the literal "" directly instead of C).
      # change the type of the constant C from Object to String.
      # create an instance of MyClass before accessing the enum (i.e. new MyClass(); before calling MyClass.State.values()).

      FREQUENCY : always


            psonal Pallavi Sonal (Inactive)
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: