Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4833719

(bf) Views of MappedByteBuffers are not MappedByteBuffers, and cannot be forced

    Details

    • Type: Enhancement
    • Status: In Progress
    • Priority: P3
    • Resolution: Unresolved
    • Affects Version/s: 1.4.1
    • Fix Version/s: None
    • Component/s: core-libs
    • Labels:
    • Subcomponent:
    • Understanding:
      Fix Understood
    • CPU:
      generic
    • OS:
      generic

      Description



      Name: nt126004 Date: 03/17/2003


      FULL PRODUCT VERSION :
      J2SE 1.4.1 and higher

      FULL OS VERSION :
      Common issue for all OSes....

      A DESCRIPTION OF THE PROBLEM :
      The .force() call on a MappedByteBuffer object fails if the buffer was cast to a MappedByteBuffer from a DirectByteBuffer object which was created with MappedByteBuffer.duplicate() or MappedByteBuffer.slice(). The problem is a call to checkMapped() method inside the MappedbyteBuffer class.

      I can change the isAMappedBuffer value in debug and force the program to do its thing properly, but there is not a way to do this within a running program. It seems like the MappedByteBuffer class should NOT throw an exception unless it is ACTUALLY not backed by a MappedByteBuffer.

      In other words, when the .duplicate() or .slice() is called, it should carry over the isAMappedBuffer from the original MappedByteBuffer object.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      1. Create a MappedByteBuffer using channel.map()
      2. MappedByteBuffer buf2 = buf.duplicate();
      3. MappedByteBuffer buf3 = (MappedByteBuffer) buf2;
      4. buf3.force();

      .force() call on DirectByteBuffer object cast to MappedByteBuffer fail if they were created with .duplicate() or .slice() from a MappedByteBuffer. The problem is a call to checkMapped() method inside the MappedbyteBuffer class. I can change the isAMappedBuffer value in debug and force the program to do its thing properly, but there is not a way to do this within a running program. It seems like the MappedByteBuffer class should NOT throw an exception unless it is ACTUALLY not backed by a MappedByteBuffer. In other words, when the .duplicate() or .slice() is called, it should carry over the isAMappedBuffer from the original MappedByteBuffer object.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      It seems like the MappedByteBuffer class should NOT throw an exception unless it is ACTUALLY NOT backed by a MappedByteBuffer.

      In other words, when the .duplicate() or .slice() is called, it should carry over the isAMappedBuffer from the original MappedByteBuffer object. This way the exception would not be thrown incorrectly and would allow the force0 to be called.
      isAMappedBuffer is set to false when the .duplicate() or slice() completes. This causes no update to MMF and Exception: UnsupportedOperationException when the .force() is called on the new duplicated or sliced buffer. You must cast the buffer back to a MappedByteBuffer in order to get access to .force().

      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      testMMF main() startup
      Exception in thread "main" java.lang.UnsupportedOperationException
              at java.nio.MappedByteBuffer.checkMapped(MappedByteBuffer.java:76)
              at java.nio.MappedByteBuffer.force(MappedByteBuffer.java:137)
              at CROSS.System.os.MMFDataBlock.flushToDisk(MMFDataBlock.java:147)
              at CROSS.System.os.MMFBufferedOutputStream.flushToDisk(MMFBufferedOutput
      Stream.java:200)
              at testMMF.main(testMMF.java:129)

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      package CROSS.ReproductBugs;

      import java.io.RandomAccessFile;
      import java.nio.*;
      import java.nio.channels.*;

      class ReproductBugs {
          ReproductBugs() {
              RandomAccessFile fileRW;
              FileChannel fcRW;
              MappedByteBuffer buf2;

              try {
                  fileRW = new RandomAccessFile("test.fil", "rwd");
              } catch (java.io.FileNotFoundException e) {
                  e.printStackTrace();
                  return;
              }

              fcRW = fileRW.getChannel();
              try {
                  if (fileRW.length() < 10000) {
                      fileRW.setLength(10000);
                  }
              } catch (java.io.IOException e) {
                  e.printStackTrace();
                  return;
              }

              MappedByteBuffer mapbufRW;
              try {
                  mapbufRW = fcRW.map(java.nio.channels.FileChannel.MapMode.READ_WRITE, 0, 10000);
              } catch (java.io.IOException e) {
                  e.printStackTrace();
                  return;
              }

              buf2 = (MappedByteBuffer) mapbufRW.duplicate();
              buf2.put("This is a test".getBytes());
              buf2.force();

          }

          public static void main(String[] args) {
              ReproductBugs rb = new ReproductBugs();
          }
      }

      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      I don't know of any solution outside of forcing the underlying MappedByteBuffer. This would require me to track that relationship with a hashmap or something on that order. This is not acceptable in some cases, in others we might be able to work with it. I can't seem to find much of anything on this topic in the the forums, etc.
      (Review ID: 182700)
      ======================================================================

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                bpb Brian Burkhalter
                Reporter:
                nthompsosunw Nathanael Thompson (Inactive)
              • Votes:
                0 Vote for this issue
                Watchers:
                0 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Imported:
                  Indexed: