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

Creating more than one array-like object causes class cast exceptions

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Duplicate
    • Icon: P4 P4
    • None
    • 8u31
    • core-libs

      FULL PRODUCT VERSION :
      java version "1.8.0_31"
      Java(TM) SE Runtime Environment (build 1.8.0_31-b13)
      Java HotSpot(TM) 64-Bit Server VM (build 25.31-b07, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      Microsoft Windows [Version 6.1.7601]

      A DESCRIPTION OF THE PROBLEM :
      This issue applies to array-like objects constructed in Nashorn. The problem is that after the first array-like object is created, any subsequent creations throw errors when referenced. This only happens when the length field is defined as the first property of the object.

      Here is an example scenario:

      import javax.script.ScriptEngine;
      import javax.script.ScriptEngineManager;
      import javax.script.ScriptException;

      public class NashornBug {
          
          public static void main(String[] args) throws ScriptException {
              
              ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
              ScriptEngine se = scriptEngineManager.getEngineByName("nashorn");
              
              se.eval("var a = {length: 3, 0: 0, 1: 0, 2: 0};\n" +
                           "var b = {length: 2, 0: 5, 1: 6};\n" +
                           "if (a.length) { print('a: ' + a.length); }\n" +
                           "if (b.length) { print('b: ' + b.length); }\n");
          }
      }

      The first array-like object 'a' behaves as expected. However, any attempt to reference, log or access properties of the second object 'b' results in the following error:
      java.lang.ClassCastException: Cannot cast jdk.nashorn.internal.scripts.JO4 to jdk.nashorn.internal.scripts.JO8

      Another quirk to this issue is that this only happens if the length property is defined first. Replacing the above script with the following seems to avoid this issue:

              se.eval("var a = {0: 0, 1: 0, 2: 0, length: 3};\n" +
                           "var b = {0: 5, 1: 6, length: 2};\n" +
                           "if (a.length) { print('a: ' + a.length); }\n" +
                           "if (b.length) { print('b: ' + b.length); }\n");


      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      a: 3
      b: 2
      ACTUAL -
      a: 3
      java.lang.ClassCastException: Cannot cast jdk.nashorn.internal.scripts.JO4 to jdk.nashorn.internal.scripts.JO8

      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      java.lang.ClassCastException: Cannot cast jdk.nashorn.internal.scripts.JO4 to jdk.nashorn.internal.scripts.JO8

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import javax.script.ScriptEngine;
      import javax.script.ScriptEngineManager;
      import javax.script.ScriptException;

      public class NashornBug {
          
          public static void main(String[] args) throws ScriptException {
              
              ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
              ScriptEngine se = scriptEngineManager.getEngineByName("nashorn");
              
              se.eval("var a = {length: 3, 0: 0, 1: 0, 2: 0};\n" +
                           "var b = {length: 2, 0: 5, 1: 6};\n" +
                           "if (a.length) { print('a: ' + a.length); }\n" +
                           "if (b.length) { print('b: ' + b.length); }\n");
          }
      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      import javax.script.ScriptEngine;
      import javax.script.ScriptEngineManager;
      import javax.script.ScriptException;

      public class NashornBug {
          
          public static void main(String[] args) throws ScriptException {
              
              ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
              ScriptEngine se = scriptEngineManager.getEngineByName("nashorn");
              //set length last
              se.eval("var a = {0: 0, 1: 0, 2: 0, length: 3};\n" +
                          "var b = {0: 5, 1: 6, length: 2};\n" +
                          "if (a.length) { print('a: ' + a.length); }\n" +
                          "if (b.length) { print('b: ' + b.length); }\n");
          }
      }

            hannesw Hannes Wallnoefer
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: