8147505: BaseStream.onClose() should not allow registering new handlers after stream is consumed
Reviewed-by: psandoz
--- a/jdk/src/java.base/share/classes/java/util/stream/AbstractPipeline.java Thu Mar 03 10:06:16 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/util/stream/AbstractPipeline.java Thu Mar 03 10:06:25 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -327,6 +327,8 @@
@Override
@SuppressWarnings("unchecked")
public S onClose(Runnable closeHandler) {
+ if (linkedOrConsumed)
+ throw new IllegalStateException(MSG_STREAM_LINKED);
Objects.requireNonNull(closeHandler);
Runnable existingHandler = sourceStage.sourceCloseAction;
sourceStage.sourceCloseAction =
--- a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/StreamCloseTest.java Thu Mar 03 10:06:16 2016 +0100
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/StreamCloseTest.java Thu Mar 03 10:06:25 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,7 +24,7 @@
/*
* @test
* @summary close handlers and closing streams
- * @bug 8044047
+ * @bug 8044047 8147505
*/
package org.openjdk.tests.java.util.stream;
@@ -37,6 +37,7 @@
import static java.util.stream.LambdaTestHelpers.countTo;
import static java.util.stream.ThowableHelper.checkNPE;
+import static java.util.stream.ThowableHelper.checkISE;
@Test(groups = { "serialization-hostile" })
public class StreamCloseTest extends OpTestCase {
@@ -170,4 +171,21 @@
for (int i=0; i<n-1; i++)
assertTrue(e.getSuppressed()[i].getMessage().equals(String.valueOf(i + 2)));
}
+
+ public void testConsumed() {
+ try(Stream<Integer> s = countTo(100).stream()) {
+ s.forEach(i -> {});
+ // Adding onClose handler when stream is consumed is illegal
+ // handler must not be registered
+ checkISE(() -> s.onClose(() -> fail("1")));
+ }
+
+ // close() must be idempotent:
+ // second close() invoked at the end of try-with-resources must have no effect
+ try(Stream<Integer> s = countTo(100).stream()) {
+ s.close();
+ // Adding onClose handler when stream is closed is also illegal
+ checkISE(() -> s.onClose(() -> fail("3")));
+ }
+ }
}