mapdb
mapdb copied to clipboard
mapdb 3.0.8 fails to fileLoad mapDB file when readOnly set
fileLoad() of mapDBfile fails when DBMaker is set to readOnly, fileLoad() succeeds if not readOnly
java.lang.UnsupportedOperationException: null
at java.nio.MappedByteBuffer.checkMapped(MappedByteBuffer.java:96) ~[?:1.8.0_302]
at java.nio.MappedByteBuffer.load(MappedByteBuffer.java:156) ~[?:1.8.0_302]
at org.mapdb.volume.MappedFileVolSingle.fileLoad(MappedFileVolSingle.java:173) ~[mapdb-3.0.8.jar:?]
at org.mapdb.StoreDirect.fileLoad(StoreDirect.kt:1112) ~[mapdb-3.0.8.jar:?]
at <our code that calls db_.getStore().fileLoad(); see below>
our calling code:
//it used STRING & JAVA for key & value serializers respectively to create the file, and the file was committed & closed
DB db = DBMaker
.fileDB(file)
.fileMmapEnableIfSupported()
.fileMmapPreclearDisable()
.fileChannelEnable()
.cleanerHackEnable()
.closeOnJvmShutdown()
.readOnly() //only fails when this is uncommented, seems you cant load a file if you set it to readOnly
.make();
db.getStore().fileLoad(); <-- fails here
http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/classes/java/nio/MappedByteBuffer.java the comment is in the java source, and it is exactly what the mapdb code is doing
private void checkMapped() {
if (fd == null)
// Can only happen if a luser explicitly casts a direct byte buffer
throw new UnsupportedOperationException();
}
https://github.com/jankotek/mapdb/blob/release-3.0/src/main/java/org/mapdb/volume/MappedFileVolSingle.java
...Constructor:
buffer = raf.getChannel().map(mapMode, 0, maxSize); //this returns a DirectByteBuffer extends MappedByteBuffer
//but its call to super() does seem to set the fd for java 8, or is done at the asReadOnlyBuffer copy
if (readOnly)
buffer = buffer.asReadOnlyBuffer(); //this calls an ByteBuffer abstract method, but the caller never sets the fd value (MappedByteBuffer has 2 constructors, one that sets fd & one that doesnt, control flow is obscured but its calling the one where fd=null, thus is not mapped
...
@Override
public boolean fileLoad() {
((MappedByteBuffer) buffer).load();
return true;
}