-
Type:
Bug
-
Resolution: Cannot Reproduce
-
Priority:
P4
-
None
-
Affects Version/s: 8u101
-
Component/s: core-libs
-
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())
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())