-
Bug
-
Resolution: Duplicate
-
P4
-
None
-
9
-
x86_64
-
windows_7
FULL PRODUCT VERSION :
java version "9"
Java(TM) SE Runtime Environment (build 9+181)
Java HotSpot(TM) 64-Bit Server VM (build 9+181, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]
A DESCRIPTION OF THE PROBLEM :
The 'limit' method is specified to be a short-circuiting operation, but when used on an infinite Stream generated through use of 'flatMap' the limit is inconsistently applied, leading to a StackOverflowError.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile and run the attached code. The problem occurs with primitive streams (IntStream and company) or the generic object Stream.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The code should print
4
3
2
1
0
and then exit cleanly
ACTUAL -
The code prints
4
3
2
1
0
and then throws a StackOverflowError
ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception in thread "main" java.lang.StackOverflowError
at java.base/java.util.stream.Streams$StreamBuilderImpl.forEachRemaining(Streams.java:411)
at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:734)
at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:591)
at java.base/java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:272)
at java.base/java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
at java.base/java.util.stream.StreamSpliterators$WrappingSpliterator.forEachRemaining(StreamSpliterators.java:312)
at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:735)
at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:591)
at java.base/java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:272)
at java.base/java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
at java.base/java.util.stream.StreamSpliterators$WrappingSpliterator.forEachRemaining(StreamSpliterators.java:312)
at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:735)
at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:591)
at java.base/java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:272)
(etc.)
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.util.IntStream;
public class StreamBugTest {
public static void main(String[] args) {
getChildren(5).limit(5).forEach(System.out::println);
}
private static IntStream getChildren(int i) {
return IntStream.rangeClosed(i - 1, i + 1).flatMap(c -> IntStream.concat(IntStream.of(c), StreamBugTest .getChildren(c)));
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Must re-write code
java version "9"
Java(TM) SE Runtime Environment (build 9+181)
Java HotSpot(TM) 64-Bit Server VM (build 9+181, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]
A DESCRIPTION OF THE PROBLEM :
The 'limit' method is specified to be a short-circuiting operation, but when used on an infinite Stream generated through use of 'flatMap' the limit is inconsistently applied, leading to a StackOverflowError.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile and run the attached code. The problem occurs with primitive streams (IntStream and company) or the generic object Stream.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The code should print
4
3
2
1
0
and then exit cleanly
ACTUAL -
The code prints
4
3
2
1
0
and then throws a StackOverflowError
ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception in thread "main" java.lang.StackOverflowError
at java.base/java.util.stream.Streams$StreamBuilderImpl.forEachRemaining(Streams.java:411)
at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:734)
at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:591)
at java.base/java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:272)
at java.base/java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
at java.base/java.util.stream.StreamSpliterators$WrappingSpliterator.forEachRemaining(StreamSpliterators.java:312)
at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:735)
at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:591)
at java.base/java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:272)
at java.base/java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
at java.base/java.util.stream.StreamSpliterators$WrappingSpliterator.forEachRemaining(StreamSpliterators.java:312)
at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:735)
at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:591)
at java.base/java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:272)
(etc.)
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.util.IntStream;
public class StreamBugTest {
public static void main(String[] args) {
getChildren(5).limit(5).forEach(System.out::println);
}
private static IntStream getChildren(int i) {
return IntStream.rangeClosed(i - 1, i + 1).flatMap(c -> IntStream.concat(IntStream.of(c), StreamBugTest .getChildren(c)));
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Must re-write code
- duplicates
-
JDK-8196106 Support nested infinite or recursive flat mapped streams
- Resolved
- relates to
-
JDK-8075939 Stream.flatMap() causes breaking of short-circuiting of terminal operations
- Resolved