Details

    • Type: Bug Bug
    • Status: Open
    • Priority: Major Major
    • Resolution: Unresolved
    • Affects Version/s: 1.2.2
    • Fix Version/s: None
    • Component/s: filesystem
    • Labels:
      None
    • Environment:

      Unix x64 (test on centos 6.5)

      Description

      This problem seems affect the Unix system (I dont' have this problem with win7 x64). For a project, I test multiple solutions to manage "a transactional filesystem". My transactional service must be able to write into a file (appending or not).
      The following test scenario illustrates the bug. I have on my disk a file with a serialized map ( a JSON serialization with a map of beans):

      {"meta2":"key":"key2","value":"value2","type":"USER"}

      ,"meta1":"key":"key1","value":"value1","type":"TECHNICAL"}}

      My transactional service must update this file with a new serialized map:

      {"meta3":{"key":"key3","value":"value3","type":"TECHNICAL"}}

      The transactional method calls a XADisk storage connector. To avoid to append the new map in the file I use the truncate method:

      session.truncateFile(file, 0);
      try (OutputStream out = new XAFileOutputStreamWrapper(session.createXAFileOutputStream(file, true))) {
      try (InputStream in = source.getInputStream())

      { IOUtils.copy(in, out); }

      } catch (FileNotExistsException | NoTransactionAssociatedException | InterruptedException | IOException | FileUnderUseException e) {
      ...
      }

      In the transaction I throw an exception to cause a rollback. I expect to have the initial file with the following information:

      {"meta2":"key":"key2","value":"value2","type":"USER"}

      ,"meta1":"key":"key1","value":"value1","type":"TECHNICAL"}}

      But the file contains:

      {"meta3":"key":"key3","value":"value3","type":"TECHNICAL"}}"meta2":"key":"key2","value":"value2","type":"USER"}

      The first point is the file is inconsistent and it seems that the truncate method is equivalent to a insert a the beginning of the file.

      Best regards.

        Activity

        Hide
        Nitin Verma added a comment -

        I find that the below code does not work as expected on the linux installation:
        ______________________________

        File s = new File("C:/a.txt");
        File d = new File("C:/b.txt");
        FileChannel fcs = new FileInputStream(s).getChannel();
        FileChannel fcd = new FileOutputStream(d, true).getChannel();
        fcd.transferFrom(fcs, 3, 10);
        ______________________________

        From the javadoc of FileChannel.transferFrom, one would expect the bytes transfer to begin at 3rd position of the destination file. This works fine on my windows xp installation, but on linux it appends at the end of the destination file. Note that using "append=false" for opening FileOutputStream truncates the file immediately (even before starting to write into the file).

        Seems like a bug to me.

        Any opinions?

        Show
        Nitin Verma added a comment - I find that the below code does not work as expected on the linux installation: ______________________________ File s = new File("C:/a.txt"); File d = new File("C:/b.txt"); FileChannel fcs = new FileInputStream(s).getChannel(); FileChannel fcd = new FileOutputStream(d, true).getChannel(); fcd.transferFrom(fcs, 3, 10); ______________________________ From the javadoc of FileChannel.transferFrom, one would expect the bytes transfer to begin at 3rd position of the destination file. This works fine on my windows xp installation, but on linux it appends at the end of the destination file. Note that using "append=false" for opening FileOutputStream truncates the file immediately (even before starting to write into the file). Seems like a bug to me. Any opinions?
        Hide
        Jasper Siepkes added a comment -

        Well the doc ( http://docs.oracle.com/javase/7/docs/api/java/nio/channels/FileChannel.html#transferFrom%28java.nio.channels.ReadableByteChannel,%20long,%20long%29 ) says "An attempt is made to read up to count bytes from the source channel and write them to this channel's file starting at the given position." (with position being written in monospaced font to signify its an method argument). So yeah one would expect that, JVM bug perhaps?. Which JVM version are you using on Linux Nitin?

        Show
        Jasper Siepkes added a comment - Well the doc ( http://docs.oracle.com/javase/7/docs/api/java/nio/channels/FileChannel.html#transferFrom%28java.nio.channels.ReadableByteChannel,%20long,%20long%29 ) says "An attempt is made to read up to count bytes from the source channel and write them to this channel's file starting at the given position." (with position being written in monospaced font to signify its an method argument). So yeah one would expect that, JVM bug perhaps?. Which JVM version are you using on Linux Nitin?
        Hide
        Nitin Verma added a comment - - edited

        Hello Jasper,

        I think it was 1.6. I will confirm it and update (need to reboot and switch OS etc )

        Nitin

        Show
        Nitin Verma added a comment - - edited Hello Jasper, I think it was 1.6. I will confirm it and update (need to reboot and switch OS etc ) Nitin
        Hide
        Nitin Verma added a comment -

        I did some jdk source code analysis and came to know:

        1. the same bug on Linux would also occur (and as tested, it does) for write(ByteBuffer, int), where the second argument for position in the file is being ignored if the fileChannel was opened in append mode. Basically, the following code too does not work as expected:
        File d = new File ("b.txt");
        FileChannel fcd = new FileOutputStream (d, true).getChannel ();
        ByteBuffer bb = ByteBuffer.wrap("bytebuffer".getBytes());
        fcd.write(bb, 3);

        It does not write at the position of 3, but simply appends.

        2. The code flow analysis takes us to the method pwrite0 in http://hg.openjdk.java.net/jdk6/jdk6/jdk/file/b6c45a8b14fb/src/solaris/native/sun/nio/ch/FileDispatcher.c. This further makes use of a library function pwrite64.

        3. I wrote a simple c code to verify that even pwrite64 does not work as expected on the linux machine:
        FILE *f = fopen("b.txt", "a");
        printf("%d", pwrite64(fileno(f), "tobewritten, 8, 3));

        This too appends at the end of the file.

        4. Came to see that the man page here says it is a known bug with pwrite64:
        http://linux.die.net/man/2/pwrite64: "However, on Linux, if a file is opened with O_APPEND, pwrite() appends data to the end of the file, regardless of the value of offset. "

        Show
        Nitin Verma added a comment - I did some jdk source code analysis and came to know: 1. the same bug on Linux would also occur (and as tested, it does) for write(ByteBuffer, int), where the second argument for position in the file is being ignored if the fileChannel was opened in append mode. Basically, the following code too does not work as expected: File d = new File ("b.txt"); FileChannel fcd = new FileOutputStream (d, true).getChannel (); ByteBuffer bb = ByteBuffer.wrap("bytebuffer".getBytes()); fcd.write(bb, 3); It does not write at the position of 3, but simply appends. 2. The code flow analysis takes us to the method pwrite0 in http://hg.openjdk.java.net/jdk6/jdk6/jdk/file/b6c45a8b14fb/src/solaris/native/sun/nio/ch/FileDispatcher.c . This further makes use of a library function pwrite64. 3. I wrote a simple c code to verify that even pwrite64 does not work as expected on the linux machine: FILE *f = fopen("b.txt", "a"); printf("%d", pwrite64(fileno(f), "tobewritten, 8, 3)); This too appends at the end of the file. 4. Came to see that the man page here says it is a known bug with pwrite64: http://linux.die.net/man/2/pwrite64: "However, on Linux, if a file is opened with O_APPEND, pwrite() appends data to the end of the file, regardless of the value of offset. "
        Hide
        Nitin Verma added a comment -

        I will check if we can workaround this jdk bug in xadisk source, wherever it can affect us, including the place being discussed here.

        Show
        Nitin Verma added a comment - I will check if we can workaround this jdk bug in xadisk source, wherever it can affect us, including the place being discussed here.

          People

          • Assignee:
            Nitin Verma
            Reporter:
            hell_keeper
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated: