class RemoteFileDescriptor extends RemoteFileDescriptorBase<Void> {

  @Override
  public synchronized void close() throws IOException {
    FileDescriptor fd = getFileDescriptor();
    if (fd != null && fd.valid()) {
      new FileInputStream(fd).close();
    }
  }

}

class RemoteFileDescriptorTest {

  private static final String TEST_SERVICE_NAME;
  private static final byte[] HELLO_WORLD;
  private static final byte[] SMILEY;
  private static AFUNIXNaming namingInstance;
  private static RemoteFileDescriptorTestServiceImpl testService;

  @Test
  public void testWriteAndReadHello() throws Exception {

    RemoteFileDescriptorTestService svc = (RemoteFileDescriptorTestService) namingInstance
        .getRegistry().lookup(TEST_SERVICE_NAME);

    try (FileOutputStream fos = svc.output().asFileOutputStream()) {
      fos.write(HELLO_WORLD);
    }
    svc.verifyContents(HELLO_WORLD);

    try (FileInputStream fin = svc.input(12).asFileInputStream()) {
      byte[] data = TestUtils.readAllBytes(fin);
      assertArrayEquals(SMILEY, data);
    }

    try (NaiveFileInputStreamRemote rfis = svc.naiveInputStreamRemote();
        FileInputStream fin = rfis.getRemoteFileDescriptor().asFileInputStream()) {
      assertEquals('H', rfis.read());
      assertEquals('e', fin.read());
      assertEquals('l', fin.read());
      assertEquals('l', fin.read());
      fin.close(); // it's OK to close the remote file descriptor we received via RMI
      assertEquals('o', rfis.read());
    }
  }

}