java.lang.IllegalAccessError when StringBuilder#length is called as method reference

XMLWordPrintable

    • generic
    • generic

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

      ADDITIONAL OS VERSION INFORMATION :
      Microsoft Windows [Version 10.0.10586]

      EXTRA RELEVANT SYSTEM CONFIGURATION :
      Built using Maven 3.3.9

      A DESCRIPTION OF THE PROBLEM :
      When the method StringBuilder#length is used as a method reference and then executed, java throws a IllegalAccessError. If the method is used as a lambda expression instead, no exception is thrown.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Stream over a collection of StringBuilders using Collection.stream().
      Map every StringBuilder to an int using .mapToInt(StringBuilder::length).
      Terminate the stream. The exception is now thrown.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Referencing StringBuilder::length should give exactly the same result as the lambda:
          (StringBuilder sb) -> sb.length()

      ACTUAL -
      An exception is thrown.

      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      Exception in thread "main" java.lang.IllegalAccessError: tried to access class java.lang.AbstractStringBuilder from class com.github.pyknic.mavenproject36.Main
              at com.github.pyknic.mavenproject36.Main.lambda$main$0(Main.java:18)
              at java.util.stream.ReferencePipeline$4$1.accept(Unknown Source)
              at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(Unknown Source)
              at java.util.stream.AbstractPipeline.copyInto(Unknown Source)
              at java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source)
              at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(Unknown Source)
              at java.util.stream.AbstractPipeline.evaluate(Unknown Source)
              at java.util.stream.IntPipeline.reduce(Unknown Source)
              at java.util.stream.IntPipeline.max(Unknown Source)
              at com.github.pyknic.mavenproject36.Main.main(Main.java:19)

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      @org.junit.Test
      public void test() {
          final int maxLength =
              java.util.stream.Stream.of(
                  new StringBuilder("A"),
                  new StringBuilder("BB"),
                  new StringBuilder("CCC")
              )
              .mapToInt(StringBuilder::length)
              .max().orElse(0); // IllegalAccesException

          org.junit.Assert.assertEquals(3, maxLength);
      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Never use the double-colon "::" operator when referencing methods in StringBuilder. Instead, use a lambda expression that invokes the method.

      Example:
      replace .mapToInt(StringBuilder::length)
      with .mapToInt(sb -> sb.length())

            Assignee:
            Pallavi Sonal (Inactive)
            Reporter:
            Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: