0

I have encountered with I/O issue in my java program. My program uses java 7 with Tomcat 7 under Linux. Thread 1 creates an object and serialize it to file with JAXB:

public static void export1(JAXBContext context, Object object, Path filePath){
    try {
        Marshaller marshaller = context.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
        marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
        marshaller.marshal(object, filePath.toFile());
    } catch (JAXBException e) {
        throw new RuntimeException(e);
    }
}

Then a notification is sent to external entities. Threads that handles incoming requests encounter with:

Caused by: java.nio.file.NoSuchFileException: PATH_TO_FILE
    at sun.nio.fs.UnixException.translateToIOException(Unknown Source)
    at sun.nio.fs.UnixException.rethrowAsIOException(Unknown Source)
    at sun.nio.fs.UnixException.rethrowAsIOException(Unknown Source)
    at sun.nio.fs.UnixFileSystemProvider.newByteChannel(Unknown Source)
    at java.nio.file.Files.newByteChannel(Unknown Source)
    at java.nio.file.Files.newByteChannel(Unknown Source)

I have read some posts about I/O concept flush vs sync but I am still confused. Will refactor my code to the next code that uses unbuffered output stream solve my issue?

public static void export2(JAXBContext context, Object object, Path filePath){
    try (OutputStream os = Files.newOutputStream(filePath)) {
        Marshaller marshaller = context.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
        marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
        marshaller.marshal(object, os);
    } catch (JAXBException | IOException e) {
        throw new RuntimeException(e);
    }
}

Or should I use File descriptor directly to synchronize OS buffers with underlying device?

public static void export3(JAXBContext context, Object object, Path filePath) {
    try (FileOutputStream fos = new FileOutputStream(filePath.toFile())) {
        Marshaller marshaller = context.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
        marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
        marshaller.marshal(object, fos);
        fos.getFD().sync();
    } catch (JAXBException | IOException e) {
        throw new RuntimeException(e);
    }
}
Community
  • 1
  • 1
Maxim Kirilov
  • 2,639
  • 24
  • 49

0 Answers0