Skip to content

Commit

Permalink
LUCENE-6989: Improve MMapDirectory's unmapping checks to catch more n…
Browse files Browse the repository at this point in the history
…on-working cases
  • Loading branch information
uschindler committed Feb 16, 2016
1 parent 8164272 commit 2a228b3
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 10 deletions.
3 changes: 2 additions & 1 deletion lucene/CHANGES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,8 @@ Bug Fixes
* LUCENE-7019: Add two-phase iteration to GeoPointTermQueryConstantScoreWrapper.
(Robert Muir via Nick Knize)

* LUCENE-6989: Disable MMapDirectory unmap-hack for Java 9. Official support
* LUCENE-6989: Improve MMapDirectory's unmapping checks to catch more non-working
cases. The unmap-hack does not yet work with recent Java 9. Official support
will come with Lucene 6. (Uwe Schindler)

Other
Expand Down
19 changes: 10 additions & 9 deletions lucene/core/src/java/org/apache/lucene/store/MMapDirectory.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import java.security.PrivilegedExceptionAction;
import java.security.PrivilegedActionException;
import java.util.Locale;
import java.util.Objects;
import java.util.concurrent.Future;
import java.lang.reflect.Method;

Expand Down Expand Up @@ -167,16 +168,16 @@ public MMapDirectory(Path path, LockFactory lockFactory, int maxChunkSize) throw
@Override
@SuppressForbidden(reason = "Needs access to private APIs in DirectBuffer and sun.misc.Cleaner to enable hack")
public Boolean run() {
// we currently don't support Java 9+, because internal APIs changed
// and the checks done here are not complete to detect this:
if (Constants.JRE_IS_MINIMUM_JAVA9) {
return false;
}
try {
Class<?> clazz = Class.forName("java.nio.DirectByteBuffer");
Method method = clazz.getMethod("cleaner");
method.setAccessible(true);
return true;
// inspect DirectByteBuffer:
final Class<?> dbClazz = Class.forName("java.nio.DirectByteBuffer");
final Method cleanerMethod = dbClazz.getMethod("cleaner");
cleanerMethod.setAccessible(true);
// try to lookup the clean method from sun.misc.Cleaner:
final Class<?> cleanerClazz = Class.forName("sun.misc.Cleaner");
cleanerClazz.getMethod("clean"); // no setAccessible needed as everything is public!
// check return type fits cleaner class return our decision:
return Objects.equals(cleanerMethod.getReturnType(), cleanerClazz);
} catch (Exception e) {
return false;
}
Expand Down

0 comments on commit 2a228b3

Please sign in to comment.