This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-io.git


The following commit(s) were added to refs/heads/master by this push:
     new 0c00862  Prevent IllegalArgumentExceptions in 
BrokenInputStream/Reader/OutputStream/Writer (#278)
0c00862 is described below

commit 0c008628b502f14482c0094269653cdd80d37d15
Author: Rob Spoor <[email protected]>
AuthorDate: Tue Sep 28 20:35:52 2021 +0200

    Prevent IllegalArgumentExceptions in 
BrokenInputStream/Reader/OutputStream/Writer (#278)
    
    * BrokenInputStream/Reader/OutputStream/Writer use a supplier to prevent 
IllegalArgumentExceptions in try-with-resources
    
    * Processed feedback from PR
---
 .../apache/commons/io/input/BrokenInputStream.java | 33 +++++++++++++-------
 .../org/apache/commons/io/input/BrokenReader.java  | 35 +++++++++++++--------
 .../commons/io/output/BrokenOutputStream.java      | 36 ++++++++++++++++------
 .../org/apache/commons/io/output/BrokenWriter.java | 29 +++++++++++------
 .../commons/io/input/BrokenInputStreamTest.java    | 16 ++++++++--
 .../apache/commons/io/input/BrokenReaderTest.java  | 17 ++++++++--
 .../commons/io/output/BrokenOutputStreamTest.java  | 17 ++++++++--
 .../apache/commons/io/output/BrokenWriterTest.java | 17 ++++++++--
 8 files changed, 151 insertions(+), 49 deletions(-)

diff --git a/src/main/java/org/apache/commons/io/input/BrokenInputStream.java 
b/src/main/java/org/apache/commons/io/input/BrokenInputStream.java
index 03131d0..4d84625 100644
--- a/src/main/java/org/apache/commons/io/input/BrokenInputStream.java
+++ b/src/main/java/org/apache/commons/io/input/BrokenInputStream.java
@@ -18,6 +18,7 @@ package org.apache.commons.io.input;
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.function.Supplier;
 
 /**
  * Always throws an {@link IOException} from all the {@link InputStream} 
methods where the exception is declared.
@@ -37,24 +38,34 @@ public class BrokenInputStream extends InputStream {
     public static final BrokenInputStream INSTANCE = new BrokenInputStream();
 
     /**
-     * The exception that is thrown by all methods of this class.
+     * A supplier for the exception that is thrown by all methods of this 
class.
      */
-    private final IOException exception;
+    private final Supplier<IOException> exceptionSupplier;
 
     /**
-     * Creates a new stream that always throws an {@link IOException}
+     * Creates a new stream that always throws an {@link IOException}.
      */
     public BrokenInputStream() {
-        this(new IOException("Broken input stream"));
+        this(() -> new IOException("Broken input stream"));
     }
 
     /**
      * Creates a new stream that always throws the given exception.
      *
-     * @param exception the exception to be thrown
+     * @param exception the exception to be thrown.
      */
     public BrokenInputStream(final IOException exception) {
-        this.exception = exception;
+        this(() -> exception);
+    }
+
+    /**
+     * Creates a new stream that always throws an {@link IOException}.
+     *
+     * @param exceptionSupplier a supplier for the exception to be thrown.
+     * @since 2.12.0
+     */
+    public BrokenInputStream(final Supplier<IOException> exceptionSupplier) {
+        this.exceptionSupplier = exceptionSupplier;
     }
 
     /**
@@ -65,7 +76,7 @@ public class BrokenInputStream extends InputStream {
      */
     @Override
     public int available() throws IOException {
-        throw exception;
+        throw exceptionSupplier.get();
     }
 
     /**
@@ -75,7 +86,7 @@ public class BrokenInputStream extends InputStream {
      */
     @Override
     public void close() throws IOException {
-        throw exception;
+        throw exceptionSupplier.get();
     }
 
     /**
@@ -86,7 +97,7 @@ public class BrokenInputStream extends InputStream {
      */
     @Override
     public int read() throws IOException {
-        throw exception;
+        throw exceptionSupplier.get();
     }
 
     /**
@@ -96,7 +107,7 @@ public class BrokenInputStream extends InputStream {
      */
     @Override
     public synchronized void reset() throws IOException {
-        throw exception;
+        throw exceptionSupplier.get();
     }
 
     /**
@@ -108,7 +119,7 @@ public class BrokenInputStream extends InputStream {
      */
     @Override
     public long skip(final long n) throws IOException {
-        throw exception;
+        throw exceptionSupplier.get();
     }
 
 }
diff --git a/src/main/java/org/apache/commons/io/input/BrokenReader.java 
b/src/main/java/org/apache/commons/io/input/BrokenReader.java
index 931971a..9748933 100644
--- a/src/main/java/org/apache/commons/io/input/BrokenReader.java
+++ b/src/main/java/org/apache/commons/io/input/BrokenReader.java
@@ -18,6 +18,7 @@ package org.apache.commons.io.input;
 
 import java.io.IOException;
 import java.io.Reader;
+import java.util.function.Supplier;
 
 /**
  * Always throws an {@link IOException} from all the {@link Reader} methods 
where the exception is declared.
@@ -37,24 +38,34 @@ public class BrokenReader extends Reader {
     public static final BrokenReader INSTANCE = new BrokenReader();
 
     /**
-     * The exception that is thrown by all methods of this class.
+     * A supplier for the exception that is thrown by all methods of this 
class.
      */
-    private final IOException exception;
+    private final Supplier<IOException> exceptionSupplier;
 
     /**
-     * Creates a new reader that always throws an {@link IOException}
+     * Creates a new reader that always throws an {@link IOException}.
      */
     public BrokenReader() {
-        this(new IOException("Broken reader"));
+        this(() -> new IOException("Broken reader"));
     }
 
     /**
      * Creates a new reader that always throws the given exception.
      *
-     * @param exception the exception to be thrown
+     * @param exception the exception to be thrown.
      */
     public BrokenReader(final IOException exception) {
-        this.exception = exception;
+        this(() -> exception);
+    }
+
+    /**
+     * Creates a new reader that always throws an {@link IOException}
+     *
+     * @param exceptionSupplier a supplier for the exception to be thrown.
+     * @since 2.12.0
+     */
+    public BrokenReader(final Supplier<IOException> exceptionSupplier) {
+        this.exceptionSupplier = exceptionSupplier;
     }
 
     /**
@@ -64,7 +75,7 @@ public class BrokenReader extends Reader {
      */
     @Override
     public void close() throws IOException {
-        throw exception;
+        throw exceptionSupplier.get();
     }
 
     /**
@@ -75,7 +86,7 @@ public class BrokenReader extends Reader {
      */
     @Override
     public void mark(final int readAheadLimit) throws IOException {
-        throw exception;
+        throw exceptionSupplier.get();
     }
 
     /**
@@ -89,7 +100,7 @@ public class BrokenReader extends Reader {
      */
     @Override
     public int read(final char[] cbuf, final int off, final int len) throws 
IOException {
-        throw exception;
+        throw exceptionSupplier.get();
     }
 
     /**
@@ -100,7 +111,7 @@ public class BrokenReader extends Reader {
      */
     @Override
     public boolean ready() throws IOException {
-        throw exception;
+        throw exceptionSupplier.get();
     }
 
     /**
@@ -110,7 +121,7 @@ public class BrokenReader extends Reader {
      */
     @Override
     public synchronized void reset() throws IOException {
-        throw exception;
+        throw exceptionSupplier.get();
     }
 
     /**
@@ -122,7 +133,7 @@ public class BrokenReader extends Reader {
      */
     @Override
     public long skip(final long n) throws IOException {
-        throw exception;
+        throw exceptionSupplier.get();
     }
 
 }
diff --git a/src/main/java/org/apache/commons/io/output/BrokenOutputStream.java 
b/src/main/java/org/apache/commons/io/output/BrokenOutputStream.java
index 4c4ec40..59d655a 100644
--- a/src/main/java/org/apache/commons/io/output/BrokenOutputStream.java
+++ b/src/main/java/org/apache/commons/io/output/BrokenOutputStream.java
@@ -18,6 +18,7 @@ package org.apache.commons.io.output;
 
 import java.io.IOException;
 import java.io.OutputStream;
+import java.util.function.Supplier;
 
 /**
  * Broken output stream. This stream always throws an {@link IOException} from
@@ -32,24 +33,41 @@ import java.io.OutputStream;
 public class BrokenOutputStream extends OutputStream {
 
     /**
-     * The exception that is thrown by all methods of this class.
+     * A singleton instance.
+     *
+     * @since 2.12.0
      */
-    private final IOException exception;
+    public static final BrokenOutputStream INSTANCE = new BrokenOutputStream();
 
     /**
-     * Creates a new stream that always throws an {@link IOException}
+     * A supplier for the exception that is thrown by all methods of this 
class.
+     */
+    private final Supplier<IOException> exceptionSupplier;
+
+    /**
+     * Creates a new stream that always throws an {@link IOException}.
      */
     public BrokenOutputStream() {
-        this(new IOException("Broken output stream"));
+        this(() -> new IOException("Broken output stream"));
     }
 
     /**
      * Creates a new stream that always throws the given exception.
      *
-     * @param exception the exception to be thrown
+     * @param exception the exception to be thrown.
      */
     public BrokenOutputStream(final IOException exception) {
-        this.exception = exception;
+        this(() -> exception);
+    }
+
+    /**
+     * Creates a new stream that always throws an {@link IOException}.
+     *
+     * @param exceptionSupplier a supplier for the exception to be thrown.
+     * @since 2.12.0
+     */
+    public BrokenOutputStream(final Supplier<IOException> exceptionSupplier) {
+        this.exceptionSupplier = exceptionSupplier;
     }
 
     /**
@@ -59,7 +77,7 @@ public class BrokenOutputStream extends OutputStream {
      */
     @Override
     public void close() throws IOException {
-        throw exception;
+        throw exceptionSupplier.get();
     }
 
     /**
@@ -69,7 +87,7 @@ public class BrokenOutputStream extends OutputStream {
      */
     @Override
     public void flush() throws IOException {
-        throw exception;
+        throw exceptionSupplier.get();
     }
 
     /**
@@ -80,7 +98,7 @@ public class BrokenOutputStream extends OutputStream {
      */
     @Override
     public void write(final int b) throws IOException {
-        throw exception;
+        throw exceptionSupplier.get();
     }
 
 }
diff --git a/src/main/java/org/apache/commons/io/output/BrokenWriter.java 
b/src/main/java/org/apache/commons/io/output/BrokenWriter.java
index d49eff3..9755a53 100644
--- a/src/main/java/org/apache/commons/io/output/BrokenWriter.java
+++ b/src/main/java/org/apache/commons/io/output/BrokenWriter.java
@@ -18,6 +18,7 @@ package org.apache.commons.io.output;
 
 import java.io.IOException;
 import java.io.Writer;
+import java.util.function.Supplier;
 
 /**
  * Always throws an {@link IOException} from all {@link Writer} methods.
@@ -37,24 +38,34 @@ public class BrokenWriter extends Writer {
     public static final BrokenWriter INSTANCE = new BrokenWriter();
 
     /**
-     * The exception that is thrown by all methods of this class.
+     * A supplier for the exception that is thrown by all methods of this 
class.
      */
-    private final IOException exception;
+    private final Supplier<IOException> exceptionSupplier;
 
     /**
-     * Creates a new writer that always throws an {@link IOException}
+     * Creates a new writer that always throws an {@link IOException}.
      */
     public BrokenWriter() {
-        this(new IOException("Broken writer"));
+        this(() -> new IOException("Broken writer"));
     }
 
     /**
      * Creates a new writer that always throws the given exception.
      *
-     * @param exception the exception to be thrown
+     * @param exception the exception to be thrown.
      */
     public BrokenWriter(final IOException exception) {
-        this.exception = exception;
+        this(() -> exception);
+    }
+
+    /**
+     * Creates a new writer that always throws an {@link IOException}.
+     *
+     * @param exceptionSupplier a supplier for the exception to be thrown.
+     * @since 2.12.0
+     */
+    public BrokenWriter(final Supplier<IOException> exceptionSupplier) {
+        this.exceptionSupplier = exceptionSupplier;
     }
 
     /**
@@ -64,7 +75,7 @@ public class BrokenWriter extends Writer {
      */
     @Override
     public void close() throws IOException {
-        throw exception;
+        throw exceptionSupplier.get();
     }
 
     /**
@@ -74,7 +85,7 @@ public class BrokenWriter extends Writer {
      */
     @Override
     public void flush() throws IOException {
-        throw exception;
+        throw exceptionSupplier.get();
     }
 
     /**
@@ -87,7 +98,7 @@ public class BrokenWriter extends Writer {
      */
     @Override
     public void write(final char[] cbuf, final int off, final int len) throws 
IOException {
-        throw exception;
+        throw exceptionSupplier.get();
     }
 
 }
diff --git 
a/src/test/java/org/apache/commons/io/input/BrokenInputStreamTest.java 
b/src/test/java/org/apache/commons/io/input/BrokenInputStreamTest.java
index 62727dc..9fe8658 100644
--- a/src/test/java/org/apache/commons/io/input/BrokenInputStreamTest.java
+++ b/src/test/java/org/apache/commons/io/input/BrokenInputStreamTest.java
@@ -18,10 +18,8 @@ package org.apache.commons.io.input;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertThrows;
-
 import java.io.IOException;
 import java.io.InputStream;
-
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
@@ -67,4 +65,18 @@ public class BrokenInputStreamTest {
         assertEquals(exception, assertThrows(IOException.class, () -> 
stream.skip(1)));
     }
 
+    @Test
+    public void testTryWithResources() {
+        final IOException thrown = assertThrows(IOException.class, () -> {
+            try (InputStream newStream = new BrokenInputStream()) {
+                newStream.read();
+            }
+        });
+        assertEquals("Broken input stream", thrown.getMessage());
+
+        final Throwable[] suppressed = thrown.getSuppressed();
+        assertEquals(1, suppressed.length);
+        assertEquals(IOException.class, suppressed[0].getClass());
+        assertEquals("Broken input stream", suppressed[0].getMessage());
+    }
 }
diff --git a/src/test/java/org/apache/commons/io/input/BrokenReaderTest.java 
b/src/test/java/org/apache/commons/io/input/BrokenReaderTest.java
index ba26938..10f078b 100644
--- a/src/test/java/org/apache/commons/io/input/BrokenReaderTest.java
+++ b/src/test/java/org/apache/commons/io/input/BrokenReaderTest.java
@@ -19,10 +19,8 @@ package org.apache.commons.io.input;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertThrows;
-
 import java.io.IOException;
 import java.io.Reader;
-
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
@@ -86,4 +84,19 @@ public class BrokenReaderTest {
         assertEquals(exception, assertThrows(IOException.class, () -> 
brokenReader.skip(1)));
     }
 
+    @Test
+    public void testTryWithResources() {
+        final IOException thrown = assertThrows(IOException.class, () -> {
+            try (Reader newReader = new BrokenReader()) {
+                newReader.read();
+            }
+        });
+        assertEquals("Broken reader", thrown.getMessage());
+
+        final Throwable[] suppressed = thrown.getSuppressed();
+        assertEquals(1, suppressed.length);
+        assertEquals(IOException.class, suppressed[0].getClass());
+        assertEquals("Broken reader", suppressed[0].getMessage());
+    }
+
 }
diff --git 
a/src/test/java/org/apache/commons/io/output/BrokenOutputStreamTest.java 
b/src/test/java/org/apache/commons/io/output/BrokenOutputStreamTest.java
index e28e565..dcb331c 100644
--- a/src/test/java/org/apache/commons/io/output/BrokenOutputStreamTest.java
+++ b/src/test/java/org/apache/commons/io/output/BrokenOutputStreamTest.java
@@ -18,10 +18,8 @@ package org.apache.commons.io.output;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertThrows;
-
 import java.io.IOException;
 import java.io.OutputStream;
-
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
@@ -65,4 +63,19 @@ public class BrokenOutputStreamTest {
         assertEquals(exception, assertThrows(IOException.class, () -> 
stream.write(1)));
     }
 
+    @Test
+    public void testTryWithResources() {
+        final IOException thrown = assertThrows(IOException.class, () -> {
+            try (OutputStream newStream = new BrokenOutputStream()) {
+                newStream.write(1);
+            }
+        });
+        assertEquals("Broken output stream", thrown.getMessage());
+
+        final Throwable[] suppressed = thrown.getSuppressed();
+        assertEquals(1, suppressed.length);
+        assertEquals(IOException.class, suppressed[0].getClass());
+        assertEquals("Broken output stream", suppressed[0].getMessage());
+    }
+
 }
diff --git a/src/test/java/org/apache/commons/io/output/BrokenWriterTest.java 
b/src/test/java/org/apache/commons/io/output/BrokenWriterTest.java
index bc0e125..57d606c 100644
--- a/src/test/java/org/apache/commons/io/output/BrokenWriterTest.java
+++ b/src/test/java/org/apache/commons/io/output/BrokenWriterTest.java
@@ -18,10 +18,8 @@ package org.apache.commons.io.output;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertThrows;
-
 import java.io.IOException;
 import java.io.Writer;
-
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Disabled;
 import org.junit.jupiter.api.Test;
@@ -109,4 +107,19 @@ public class BrokenWriterTest {
         assertEquals(exception, assertThrows(IOException.class, () -> 
brokenWriter.write("01", 0, 1)));
     }
 
+    @Test
+    public void testTryWithResources() {
+        final IOException thrown = assertThrows(IOException.class, () -> {
+            try (Writer newWriter = new BrokenWriter()) {
+                newWriter.write(1);
+            }
+        });
+        assertEquals("Broken writer", thrown.getMessage());
+
+        final Throwable[] suppressed = thrown.getSuppressed();
+        assertEquals(1, suppressed.length);
+        assertEquals(IOException.class, suppressed[0].getClass());
+        assertEquals("Broken writer", suppressed[0].getMessage());
+    }
+
 }

Reply via email to