FileChannel.write(ByteBuffer src, long position) does not check to see if the FileChannel is closed prior to checking for a WritableChannel and is inconsistent with the other write methods. The javadoc is not clear on which exception should be thrown 1st but I would expect the close check to be done 1st.
Here is the example:
@Test
public void fcCCETest() throws Exception {
Path osFile = generatePath(HERE, "test", ".txt");
Files.deleteIfExists(osFile);
Files.writeString(osFile, THE_SLAMS);;
// Create the ByteBuffer array that will be used
ByteBuffer[] bb = {
ByteBuffer.wrap("First Serve".getBytes(UTF_8)),
ByteBuffer.wrap("Fault".getBytes(UTF_8)),
ByteBuffer.wrap("Double Fault".getBytes(UTF_8))
};
// Check that ClosedChannelException is thrown if the channel is closed
try (FileChannel fc = FileChannel.open(osFile, Set.of(READ))) {
fc.close();
assertThrows(ClosedChannelException.class, () -> fc.write(bb));
assertThrows(ClosedChannelException.class, () -> fc.write(bb[0]));
// Note does not check closed 1st when file not opened with "WRITE"
assertThrows(ClosedChannelException.class, () -> fc.write(bb[0], 1));
assertThrows(ClosedChannelException.class, () -> fc.write(bb, 1, 2));
}
Files.deleteIfExists(osFile);
}
The error is
----------------
java.lang.AssertionError: Expected ClosedChannelException to be thrown, but NonWritableChannelException was thrown
at org.testng.Assert.expectThrows(Assert.java:1389)
at org.testng.Assert.assertThrows(Assert.java:1364)
at test.FailingChannelTests.fcCCETest(FailingChannelTests.java:283)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:124)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:583)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:719)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:989)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109)
at org.testng.TestRunner.privateRun(TestRunner.java:648)
at org.testng.TestRunner.run(TestRunner.java:505)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:455)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:450)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:415)
at org.testng.SuiteRunner.run(SuiteRunner.java:364)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:84)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1208)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1137)
at org.testng.TestNG.runSuites(TestNG.java:1049)
at org.testng.TestNG.run(TestNG.java:1017)
at com.intellij.rt.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:66)
at com.intellij.rt.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:110)
Caused by: java.nio.channels.NonWritableChannelException
at java.base/sun.nio.ch.FileChannelImpl.write(FileChannelImpl.java:833)
at test.FailingChannelTests.lambda$fcCCETest$7(FailingChannelTests.java:283)
at org.testng.Assert.expectThrows(Assert.java:1381)
... 26 more
-----------------
Here is the example:
@Test
public void fcCCETest() throws Exception {
Path osFile = generatePath(HERE, "test", ".txt");
Files.deleteIfExists(osFile);
Files.writeString(osFile, THE_SLAMS);;
// Create the ByteBuffer array that will be used
ByteBuffer[] bb = {
ByteBuffer.wrap("First Serve".getBytes(UTF_8)),
ByteBuffer.wrap("Fault".getBytes(UTF_8)),
ByteBuffer.wrap("Double Fault".getBytes(UTF_8))
};
// Check that ClosedChannelException is thrown if the channel is closed
try (FileChannel fc = FileChannel.open(osFile, Set.of(READ))) {
fc.close();
assertThrows(ClosedChannelException.class, () -> fc.write(bb));
assertThrows(ClosedChannelException.class, () -> fc.write(bb[0]));
// Note does not check closed 1st when file not opened with "WRITE"
assertThrows(ClosedChannelException.class, () -> fc.write(bb[0], 1));
assertThrows(ClosedChannelException.class, () -> fc.write(bb, 1, 2));
}
Files.deleteIfExists(osFile);
}
The error is
----------------
java.lang.AssertionError: Expected ClosedChannelException to be thrown, but NonWritableChannelException was thrown
at org.testng.Assert.expectThrows(Assert.java:1389)
at org.testng.Assert.assertThrows(Assert.java:1364)
at test.FailingChannelTests.fcCCETest(FailingChannelTests.java:283)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:124)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:583)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:719)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:989)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109)
at org.testng.TestRunner.privateRun(TestRunner.java:648)
at org.testng.TestRunner.run(TestRunner.java:505)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:455)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:450)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:415)
at org.testng.SuiteRunner.run(SuiteRunner.java:364)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:84)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1208)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1137)
at org.testng.TestNG.runSuites(TestNG.java:1049)
at org.testng.TestNG.run(TestNG.java:1017)
at com.intellij.rt.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:66)
at com.intellij.rt.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:110)
Caused by: java.nio.channels.NonWritableChannelException
at java.base/sun.nio.ch.FileChannelImpl.write(FileChannelImpl.java:833)
at test.FailingChannelTests.lambda$fcCCETest$7(FailingChannelTests.java:283)
at org.testng.Assert.expectThrows(Assert.java:1381)
... 26 more
-----------------
- links to