1/* 2 * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23import java.io.BufferedOutputStream; 24import java.io.FilterOutputStream; 25import java.io.IOException; 26import java.io.OutputStream; 27 28/* 29 * @test 30 * @bug 8042377 31 * @summary Ensure suppressed exceptions are properly handled in close() 32 */ 33public class SuppressedException { 34 private static final String CLOSE_MESSAGE = "Close exception"; 35 private static final String FLUSH_MESSAGE = "Flush exception"; 36 private static final String SAME_MESSAGE = "Same exception"; 37 38 public static void main(String[] args) throws java.io.IOException { 39 SuppressedException test = new SuppressedException(); 40 test.test(); 41 } 42 43 private FilterOutputStream createOutputStream(OutputStream out, 44 boolean isBuffered) { 45 return isBuffered ? new BufferedOutputStream(out) : 46 new FilterOutputStream(out); 47 } 48 49 private void test() { 50 int failures = 0; 51 FilterOutputStream buf; 52 53 boolean[] isBuffered = new boolean[] {false, true}; 54 for (boolean buffered : isBuffered) { 55 System.err.println("\n>>> Buffered: " + buffered + " <<<"); 56 System.err.flush(); 57 58 try { 59 buf = createOutputStream(new OutputStreamFailsWithException(), 60 buffered); 61 buf.close(); 62 System.err.println("\nNo IOException thrown for same exception"); 63 failures++; 64 } catch (IOException expected) { 65 if (!expected.getMessage().equals(SAME_MESSAGE)) { 66 System.err.println("\nIOException with unexpected message thrown"); 67 expected.printStackTrace(); 68 failures++; 69 } 70 } catch (IllegalArgumentException unexpected) { 71 System.err.println("\nUnexpected IllegalArgumentException thrown"); 72 unexpected.printStackTrace(); 73 failures++; 74 } 75 76 try { 77 buf = createOutputStream( 78 new OutputStreamFailsWithException(false, false), 79 buffered); 80 buf.close(); 81 } catch (IOException e) { 82 System.err.println("\nUnexpected IOException thrown"); 83 e.printStackTrace(); 84 failures++; 85 } 86 87 try { 88 buf = createOutputStream( 89 new OutputStreamFailsWithException(true, false), 90 buffered); 91 buf.close(); 92 } catch (IOException e) { 93 if (!e.getMessage().equals(CLOSE_MESSAGE)) { 94 System.err.println("\nIOException with unexpected message thrown"); 95 e.printStackTrace(); 96 failures++; 97 } 98 } 99 100 try { 101 buf = createOutputStream( 102 new OutputStreamFailsWithException(false, true), 103 buffered); 104 buf.close(); 105 } catch (IOException e) { 106 if (!e.getMessage().equals(FLUSH_MESSAGE)) { 107 System.err.println("\nIOException with unexpected message thrown"); 108 e.printStackTrace(); 109 failures++; 110 } 111 } 112 113 try { 114 buf = createOutputStream( 115 new OutputStreamFailsWithException(true, true), 116 buffered); 117 buf.close(); 118 } catch (IOException e) { 119 if (!e.getMessage().equals(CLOSE_MESSAGE)) { 120 System.err.println("\nIOException with unexpected message thrown"); 121 e.printStackTrace(); 122 failures++; 123 } 124 125 Throwable[] suppressed = e.getSuppressed(); 126 if (suppressed == null) { 127 System.err.println("\nExpected suppressed exception not present"); 128 e.printStackTrace(); 129 failures++; 130 } else if (suppressed.length != 1) { 131 System.err.println("\nUnexpected number of suppressed exceptions"); 132 e.printStackTrace(); 133 failures++; 134 } else if (!(suppressed[0] instanceof IOException)) { 135 System.err.println("\nSuppressed exception is not an IOException"); 136 e.printStackTrace(); 137 failures++; 138 } else if (!suppressed[0].getMessage().equals(FLUSH_MESSAGE)) { 139 System.err.println("\nIOException with unexpected message thrown"); 140 e.printStackTrace(); 141 failures++; 142 } 143 } 144 } 145 146 if (failures > 0) { 147 throw new RuntimeException("Test failed with " + failures + " errors"); 148 } else { 149 System.out.println("Test succeeded."); 150 } 151 } 152 153 class OutputStreamFailsWithException extends OutputStream { 154 private final IOException sameException = new IOException(SAME_MESSAGE); 155 156 private final Boolean throwSeparateCloseException; 157 private final Boolean throwSeparateFlushException; 158 159 OutputStreamFailsWithException() { 160 throwSeparateCloseException = null; 161 throwSeparateFlushException = null; 162 } 163 164 OutputStreamFailsWithException(boolean throwCloseException, 165 boolean throwFlushException) { 166 throwSeparateCloseException = throwCloseException; 167 throwSeparateFlushException = throwFlushException; 168 } 169 170 @Override 171 public void write(int i) throws IOException { 172 throw new UnsupportedOperationException(""); 173 } 174 175 @Override 176 public void flush() throws IOException { 177 System.out.println("flush()"); 178 if (throwSeparateFlushException == null) { 179 throw sameException; 180 } else if (throwSeparateFlushException) { 181 throw new IOException(FLUSH_MESSAGE); 182 } 183 } 184 185 @Override 186 public void close() throws IOException { 187 System.out.println("close()"); 188 if (throwSeparateCloseException == null) { 189 throw sameException; 190 } else if (throwSeparateCloseException) { 191 throw new IOException(CLOSE_MESSAGE); 192 } 193 } 194 } 195} 196