JDK-8075939 fixed the case where a flat map operation contains an infinite stream. However, it did not fix the case where there are nested flat map calls that contain infinite streams via recursion or explicitly.
For example, here is a recursive example from JDK-8189234:
IntStream.rangeClosed(0, 1).
flatMap(Test::map).
limit(5).
forEach(System.out::println);
static IntStream getChildren() {
return IntStream.rangeClosed(0, 1).
flatMap(Test::map);
}
static IntStream map(int c) {
return IntStream.concat(
IntStream.of(c),
getChildren());
}
which will result in a StackOverlowError.
Here is another example using infinite streams:
IntStream.rangeClosed(i - 1, i + 1).
flatMap(c -> IntStream.generate(() -> 1).
flatMap(x -> IntStream.generate(() -> x))).
limit(5).forEach(System.out::println);
which will result in an OutOfMemoryError.
To solve these issues will require a mechanism to propagate the enclosing stream's cancellation function (Sink::cancellationRequested) to nested streams. Such as a terminal operation forEachOrderedWithCancel that accepts a Predicate function to query the enclosing cancellation state.
This will also avoid an issue with the spliterator obtained from a stream (AbstractWrappingSpliterator and sub-classes) which has to buffer elements to avoid reporting more than one element via Spliterator::tryAdvance (independently the implementation can be improved by directly reporting the first element and buffering subsequent elements).