[ 
https://issues.apache.org/jira/browse/LUCENE-6989?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Uwe Schindler updated LUCENE-6989:
----------------------------------
    Attachment: LUCENE-6989-v3-post-b148.patch

Here is a first patch for the planned Java 9 unmapping.

Based on the discussions on the OpenJDK mailing list the following must be 
noted and implemented.

- setAccessible() is NO LONGER POSSIBLE on any class from Java's public and 
documented class library - simple and easy - no excuses or workarounds anymore. 
There are still a few special cases (like retrieving sun.misc.Unsafe, but thats 
unsupported API anyways). This is a separate issue and requires, that 
{{RAMUsageEstimator}} in Lucene's tests and RandomizedRunner needs to be 
disabled ([~dweiss]). I will open one.
- The first implementation of the Java 9 support is now obsolete, because not 
even the {{Runnable}} approach works with above restriction.
- We proposed some "temporary workaround" for unmapping for the time beeing. 
This workaround sounds reasonable and first patches for OpenJDK are under 
discussion, but might take some time to be committed. The idea is: As 
{{sun.misc.Unsafe}} has a special role in the JDK (you can still get an 
instance of it if you respect security manager and use the well-known pattern 
to get it) and the unmapping of mmapped buffers is "unsafe" per se - why not 
add a method to unmap {{ByteBuffers}} to {{sun.misc.Unsafe}} (easy job!). 
OpenJDK patch / CR is here: 
[http://cr.openjdk.java.net/~chegar/Unsafe_invokeCleaner/]
- Java 10 might get official support for unmapping (I discussed this with 
Hotspot developers suring beers at FOSDEM 2016), the issue is here: 
https://bugs.openjdk.java.net/browse/JDK-4724038 - thanks to Andrew Haley!

The attached Lucene patch implements the addition in 
[http://cr.openjdk.java.net/~chegar/Unsafe_invokeCleaner/] (untested because 
lack of compiled JDK with that patch - I am working on that). It removes the 
pre-build-148 hack using {{Runnable}} and restores Java 8 behaviour, but adds a 
check before that, which triggers in coming Java 9 and is used for unmapping:

- Try to load class {{sun.misc.Unsafe}} (this requires security permission, 
which we already have).
- Lookup the new public (virtual method) there. This requires no security 
manager interaction.
- If this works fine, we need to get {{theUnsafe}} and bind it to our 
{{MethodHandle}}, so its gets a single-arg MH. This requires that we call 
setAccessible, that is on the special-cases and supported by Java 9 for the 
time beeing.

After that point the whole code is compatible and can be used instead of the 
more complex MH of previous versions (using {{guardWithTest}} for {{null}} 
check and {{filterReturnValue}}). This MH is returned as BufferCleaner 
functional interface - as before. The remaining code is the same, just a bit 
refactoring. I also added an extra check for direct buffers only. This mimics 
Java 9's check that would then also work in Java 8.

Please note: The new interface no longer needs the extra permission that was 
added for Java 9, it only needs 
{{RuntimePermission("accessClassInPackage.sun.misc")}} and 
{{ReflectPermission("suppressAccessChecks")}}!

> Implement MMapDirectory unmapping for coming Java 9 changes
> -----------------------------------------------------------
>
>                 Key: LUCENE-6989
>                 URL: https://issues.apache.org/jira/browse/LUCENE-6989
>             Project: Lucene - Core
>          Issue Type: Task
>          Components: core/store
>            Reporter: Uwe Schindler
>            Assignee: Uwe Schindler
>              Labels: Java9
>             Fix For: 6.0
>
>         Attachments: LUCENE-6989-disable5x.patch, 
> LUCENE-6989-disable5x.patch, LUCENE-6989-fixbuild148.patch, 
> LUCENE-6989-v2.patch, LUCENE-6989-v3-post-b148.patch, LUCENE-6989.patch, 
> LUCENE-6989.patch, LUCENE-6989.patch, LUCENE-6989.patch
>
>
> Originally, the sun.misc.Cleaner interface was declared as "critical API" in 
> [JEP 260|http://openjdk.java.net/jeps/260 ]
> Unfortunately the decission was changed in favor of a oficially supported 
> {{java.lang.ref.Cleaner}} API. A side effect of this change is to move all 
> existing {{sun.misc.Cleaner}} APIs into a non-exported package. This causes 
> our forceful unmapping to no longer work, because we can get the cleaner 
> instance via reflection, but trying to invoke it will throw one of the new 
> Jigsaw RuntimeException because it is completely inaccessible. This will make 
> our forceful unmapping fail. There are also no changes in Garbage collector, 
> the problem still exists.
> For more information see this [mailing list 
> thread|http://mail.openjdk.java.net/pipermail/core-libs-dev/2016-January/thread.html#38243].
> This commit will likely be done, making our unmapping efforts no longer 
> working. Alan Bateman is aware of this issue and will open a new issue at 
> OpenJDK to allow forceful unmapping without using the now private 
> sun.misc.Cleaner. The idea is to let the internal class sun.misc.Cleaner 
> implement the Runable interface, so we can simply cast to runable and call 
> the run() method to unmap. The code would then work. This will lead to minor 
> changes in our unmapper in MMapDirectory: An instanceof check and casting if 
> possible.
> I opened this issue to keep track and implement the changes as soon as 
> possible, so people will have working unmapping when java 9 comes out. 
> Current Lucene versions will no longer work with Java 9.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@lucene.apache.org
For additional commands, e-mail: dev-h...@lucene.apache.org

Reply via email to