1 /* 2 * Copyright (c) 2001, 2019, 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 */ 23 24 /* @test 25 * @bug 4417152 4481572 6248930 6725399 6884800 8220477 26 * @summary Test Channels basic functionality 27 */ 28 29 import java.io.*; 30 import java.nio.*; 31 import java.nio.charset.*; 32 import java.nio.channels.*; 33 34 public class Basic { 35 36 static String message; 37 38 static String encoding; 39 40 static File blah; 41 42 static int ITERATIONS = 500; 43 main(String[] args)44 public static void main(String[] args) throws Exception { 45 message = "ascii data for a test"; 46 encoding = "ISO-8859-1"; 47 test(); 48 message = "\ucafe\ubabe\ucafe\ubabe\ucafe\ubabe"; 49 encoding = "UTF-8"; 50 test(); 51 } 52 failNpeExpected()53 static void failNpeExpected() { 54 throw new RuntimeException("Did not get the expected NullPointerException."); 55 } 56 test()57 private static void test() throws Exception { 58 //Test if methods of Channels throw NPE with null argument(s) 59 try { 60 Channels.newInputStream((ReadableByteChannel)null); 61 failNpeExpected(); 62 } catch (NullPointerException npe) {} 63 64 try { 65 Channels.newOutputStream((WritableByteChannel)null); 66 failNpeExpected(); 67 } catch (NullPointerException npe) {} 68 69 try { 70 ReadableByteChannel channel = Channels.newChannel((InputStream)null); 71 failNpeExpected(); 72 } catch (NullPointerException ne) {} // OK. As expected. 73 74 try { 75 WritableByteChannel channel = Channels.newChannel((OutputStream)null); 76 failNpeExpected(); 77 } catch (NullPointerException ne) {} // OK. As expected. 78 79 WritableByteChannel wbc = new WritableByteChannel() { 80 public int write(ByteBuffer src) { return 0; } 81 public void close() throws IOException { } 82 public boolean isOpen() { return true; } 83 }; 84 85 ReadableByteChannel rbc = new ReadableByteChannel() { 86 public int read(ByteBuffer dst) { return 0; } 87 public void close() {} 88 public boolean isOpen() { return true; } 89 }; 90 91 try { 92 Channels.newReader((ReadableByteChannel)null, 93 Charset.defaultCharset().newDecoder(), 94 -1); 95 failNpeExpected(); 96 } catch (NullPointerException npe) {} 97 98 try { 99 Channels.newReader(rbc, (CharsetDecoder)null, -1); 100 failNpeExpected(); 101 } catch (NullPointerException npe) {} 102 103 try { 104 Channels.newReader((ReadableByteChannel)null, 105 Charset.defaultCharset().name()); 106 failNpeExpected(); 107 } catch (NullPointerException npe) {} 108 109 try { 110 Channels.newReader(rbc, (String)null); 111 failNpeExpected(); 112 } catch (NullPointerException npe) {} 113 114 115 try { 116 Channels.newReader(null, (String)null); 117 failNpeExpected(); 118 } catch (NullPointerException npe) {} 119 120 try { 121 Channels.newReader(rbc, (Charset)null); 122 failNpeExpected(); 123 } catch (NullPointerException npe) {} 124 125 126 try { 127 Channels.newReader(null, (Charset)null); 128 failNpeExpected(); 129 } catch (NullPointerException npe) {} 130 131 try { 132 Channels.newWriter((WritableByteChannel)null, 133 Charset.defaultCharset().newEncoder(), 134 -1); 135 failNpeExpected(); 136 } catch (NullPointerException npe) {} 137 138 try { 139 Channels.newWriter(null, null, -1); 140 failNpeExpected(); 141 } catch (NullPointerException npe) {} 142 143 try { 144 Channels.newWriter(wbc, null, -1); 145 failNpeExpected(); 146 } catch (NullPointerException npe) {} 147 148 try { 149 Channels.newWriter((WritableByteChannel)null, 150 Charset.defaultCharset().name()); 151 failNpeExpected(); 152 } catch (NullPointerException npe) {} 153 154 try { 155 Channels.newWriter(wbc, (String)null); 156 failNpeExpected(); 157 } catch (NullPointerException npe) {} 158 159 try { 160 Channels.newWriter(null, (String)null); 161 failNpeExpected(); 162 } catch (NullPointerException npe) {} 163 164 try { 165 Channels.newWriter(wbc, (Charset)null); 166 failNpeExpected(); 167 } catch (NullPointerException npe) {} 168 169 try { 170 Channels.newWriter(null, (Charset)null); 171 failNpeExpected(); 172 } catch (NullPointerException npe) {} 173 174 try { 175 blah = File.createTempFile("blah", null); 176 177 testNewOutputStream(blah); 178 readAndCheck(blah); 179 blah.delete(); 180 181 writeOut(blah, ITERATIONS); 182 testNewInputStream(blah); 183 blah.delete(); 184 185 testNewChannelOut(blah); 186 readAndCheck(blah); 187 blah.delete(); 188 189 testNewChannelWriteAfterClose(blah); 190 191 testNewChannelReadAfterClose(blah); 192 blah.delete(); 193 194 writeOut(blah, ITERATIONS); 195 testNewChannelIn(blah); 196 test4481572(blah); 197 blah.delete(); 198 199 testNewWriter(blah); 200 readAndCheck(blah); 201 blah.delete(); 202 203 writeOut(blah, ITERATIONS); 204 testNewReader(blah); 205 206 testNewWriterClose(); 207 testNewReaderClose(); 208 } finally { 209 blah.delete(); 210 } 211 } 212 readAndCheck(File blah)213 private static void readAndCheck(File blah) throws Exception { 214 FileInputStream fis = new FileInputStream(blah); 215 int messageSize = message.length() * ITERATIONS * 3 + 1; 216 byte bb[] = new byte[messageSize]; 217 int bytesRead = 0; 218 int totalRead = 0; 219 while (bytesRead != -1) { 220 totalRead += bytesRead; 221 bytesRead = fis.read(bb, totalRead, messageSize - totalRead); 222 } 223 String result = new String(bb, 0, totalRead, encoding); 224 int len = message.length(); 225 for (int i=0; i<ITERATIONS; i++) { 226 String segment = result.substring(i++ * len, i * len); 227 if (!segment.equals(message)) 228 throw new RuntimeException("Test failed"); 229 } 230 fis.close(); 231 } 232 writeOut(File blah, int limit)233 private static void writeOut(File blah, int limit) throws Exception { 234 FileOutputStream fos = new FileOutputStream(blah); 235 for (int i=0; i<limit; i++) 236 fos.write(message.getBytes(encoding)); 237 fos.close(); 238 } 239 testNewOutputStream(File blah)240 private static void testNewOutputStream(File blah) throws Exception { 241 FileOutputStream fos = new FileOutputStream(blah); 242 FileChannel fc = fos.getChannel(); 243 WritableByteChannel wbc = (WritableByteChannel)fc; 244 OutputStream os = Channels.newOutputStream(wbc); 245 for (int i=0; i<ITERATIONS; i++) 246 os.write(message.getBytes(encoding)); 247 os.close(); 248 fos.close(); 249 } 250 testNewInputStream(File blah)251 private static void testNewInputStream(File blah) throws Exception { 252 FileInputStream fis = new FileInputStream(blah); 253 FileChannel fc = fis.getChannel(); 254 InputStream is = Channels.newInputStream(fc); 255 int messageSize = message.length() * ITERATIONS * 3 + 1; 256 byte bb[] = new byte[messageSize]; 257 258 int bytesRead = 0; 259 int totalRead = 0; 260 while (bytesRead != -1) { 261 totalRead += bytesRead; 262 long rem = Math.min(fc.size() - totalRead, (long)Integer.MAX_VALUE); 263 if (is.available() != (int)rem) 264 throw new RuntimeException("available not useful or not maximally useful"); 265 bytesRead = is.read(bb, totalRead, messageSize - totalRead); 266 } 267 if (is.available() != 0) 268 throw new RuntimeException("available() should return 0 at EOF"); 269 270 String result = new String(bb, 0, totalRead, encoding); 271 int len = message.length(); 272 for (int i=0; i<ITERATIONS; i++) { 273 String segment = result.substring(i++ * len, i * len); 274 if (!segment.equals(message)) 275 throw new RuntimeException("Test failed"); 276 } 277 is.close(); 278 fis.close(); 279 } 280 testNewChannelOut(File blah)281 private static void testNewChannelOut(File blah) throws Exception { 282 ExtendedFileOutputStream fos = new ExtendedFileOutputStream(blah); 283 WritableByteChannel wbc = Channels.newChannel(fos); 284 285 for (int i=0; i<ITERATIONS; i++) 286 wbc.write(ByteBuffer.wrap(message.getBytes(encoding))); 287 wbc.close(); 288 fos.close(); 289 } 290 testNewChannelIn(File blah)291 private static void testNewChannelIn(File blah) throws Exception { 292 ExtendedFileInputStream fis = new ExtendedFileInputStream(blah); 293 ReadableByteChannel rbc = Channels.newChannel(fis); 294 295 int messageSize = message.length() * ITERATIONS * 3; 296 byte data[] = new byte[messageSize+1]; 297 ByteBuffer bb = ByteBuffer.wrap(data); 298 299 int bytesRead = 0; 300 int totalRead = 0; 301 while (bytesRead != -1) { 302 totalRead += bytesRead; 303 bytesRead = rbc.read(bb); 304 } 305 306 String result = new String(data, 0, totalRead, encoding); 307 int len = message.length(); 308 for (int i=0; i<ITERATIONS; i++) { 309 String segment = result.substring(i++ * len, i * len); 310 if (!segment.equals(message)) 311 throw new RuntimeException("Test failed"); 312 } 313 rbc.close(); 314 fis.close(); 315 } 316 testNewChannelWriteAfterClose(File blah)317 private static void testNewChannelWriteAfterClose(File blah) 318 throws Exception { 319 try (ExtendedFileOutputStream fos = 320 new ExtendedFileOutputStream(blah)) { 321 WritableByteChannel wbc = Channels.newChannel(fos); 322 323 wbc.close(); 324 try { 325 wbc.write(ByteBuffer.allocate(0)); 326 throw new RuntimeException 327 ("No ClosedChannelException on WritableByteChannel::write"); 328 } catch (ClosedChannelException expected) { 329 } 330 } 331 } 332 testNewChannelReadAfterClose(File blah)333 private static void testNewChannelReadAfterClose(File blah) 334 throws Exception { 335 try (ExtendedFileInputStream fis = new ExtendedFileInputStream(blah)) { 336 ReadableByteChannel rbc = Channels.newChannel(fis); 337 338 rbc.close(); 339 try { 340 rbc.read(ByteBuffer.allocate(0)); 341 throw new RuntimeException 342 ("No ClosedChannelException on ReadableByteChannel::read"); 343 } catch (ClosedChannelException expected) { 344 } 345 } 346 } 347 348 // Causes BufferOverflowException if bug 4481572 is present. test4481572(File blah)349 private static void test4481572(File blah) throws Exception { 350 ExtendedFileInputStream fis = new ExtendedFileInputStream(blah); 351 ReadableByteChannel rbc = Channels.newChannel(fis); 352 353 byte data[] = new byte[9000]; 354 ByteBuffer bb = ByteBuffer.wrap(data); 355 356 int bytesRead = 1; 357 int totalRead = 0; 358 while (bytesRead > 0) { 359 totalRead += bytesRead; 360 bytesRead = rbc.read(bb); 361 } 362 rbc.close(); 363 fis.close(); 364 } 365 testNewWriter(File blah)366 private static void testNewWriter(File blah) throws Exception { 367 FileOutputStream fos = new FileOutputStream(blah); 368 WritableByteChannel wbc = (WritableByteChannel)fos.getChannel(); 369 Writer w = Channels.newWriter(wbc, encoding); 370 char data[] = new char[40]; 371 message.getChars(0, message.length(), data, 0); 372 for (int i=0; i<ITERATIONS; i++) 373 w.write(data, 0, message.length()); 374 w.flush(); 375 w.close(); 376 fos.close(); 377 } 378 testNewReader(File blah)379 private static void testNewReader(File blah) throws Exception { 380 FileInputStream fis = new FileInputStream(blah); 381 ReadableByteChannel rbc = (ReadableByteChannel)fis.getChannel(); 382 Reader r = Channels.newReader(rbc, encoding); 383 384 int messageSize = message.length() * ITERATIONS; 385 char data[] = new char[messageSize]; 386 387 int totalRead = 0; 388 int charsRead = 0; 389 while (totalRead < messageSize) { 390 totalRead += charsRead; 391 charsRead = r.read(data, totalRead, messageSize - totalRead); 392 } 393 String result = new String(data, 0, totalRead); 394 int len = message.length(); 395 for (int i=0; i<ITERATIONS; i++) { 396 String segment = result.substring(i++ * len, i * len); 397 if (!segment.equals(message)) 398 throw new RuntimeException("Test failed"); 399 } 400 r.close(); 401 fis.close(); 402 } 403 testNewWriterClose()404 private static void testNewWriterClose() throws Exception { 405 Writer writer = null; 406 try { 407 WritableByteChannel channel = new WritableByteChannel() { 408 @Override 409 public int write(ByteBuffer src) throws IOException { 410 return 0; 411 } 412 413 @Override 414 public boolean isOpen() { 415 return true; 416 } 417 418 @Override 419 public void close() throws IOException { 420 throw new IOException(); 421 } 422 }; 423 writer = Channels.newWriter(channel, 424 StandardCharsets.UTF_8.newEncoder(), -1); 425 writer.close(); 426 } catch (IOException ioe) { 427 Exception theException = null; 428 try { 429 writer.write(1); 430 writer.flush(); 431 } catch (Exception e) { 432 theException = e; 433 } finally { 434 if (theException == null) { 435 throw new RuntimeException("IOException not thrown"); 436 } else if (!(theException instanceof IOException)) { 437 throw new RuntimeException("Exception not an IOException: " 438 + theException); 439 } else { 440 String message = theException.getMessage(); 441 if (!message.equals("Stream closed")) { 442 throw new RuntimeException("Unexpected message " 443 + message); 444 } 445 } 446 } 447 } 448 } 449 testNewReaderClose()450 private static void testNewReaderClose() throws Exception { 451 Reader reader = null; 452 try { 453 ReadableByteChannel channel = new ReadableByteChannel() { 454 @Override 455 public int read(ByteBuffer dst) throws IOException { 456 dst.put((byte)7); 457 return 1; 458 } 459 460 @Override 461 public boolean isOpen() { 462 return true; 463 } 464 465 @Override 466 public void close() throws IOException { 467 throw new IOException(); 468 } 469 }; 470 reader = Channels.newReader(channel, 471 StandardCharsets.UTF_8.newDecoder(), -1); 472 reader.close(); 473 } catch (IOException ioe) { 474 Exception theException = null; 475 try { 476 reader.read(); 477 } catch (Exception e) { 478 theException = e; 479 } finally { 480 if (theException == null) { 481 throw new RuntimeException("IOException not thrown"); 482 } else if (!(theException instanceof IOException)) { 483 throw new RuntimeException("Exception not an IOException: " 484 + theException); 485 } else { 486 String message = theException.getMessage(); 487 if (!message.equals("Stream closed")) { 488 throw new RuntimeException("Unexpected message " 489 + message); 490 } 491 } 492 } 493 } 494 } 495 } 496 497 class ExtendedFileInputStream extends java.io.FileInputStream { ExtendedFileInputStream(File file)498 ExtendedFileInputStream(File file) throws FileNotFoundException { 499 super(file); 500 } 501 } 502 503 class ExtendedFileOutputStream extends java.io.FileOutputStream { ExtendedFileOutputStream(File file)504 ExtendedFileOutputStream(File file) throws FileNotFoundException { 505 super(file); 506 } 507 } 508