Hi,

sorry I did not read all, so you already use my code:

The exception you see is coming from the fact that the first part for Java 9 
does not work at all. It looks like the code uses Java 8 variant (see line 
number in exception) instead of the Java 9 variant.

Can you make a breakpoint here: 
https://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/nio/CleanerUtil.java?view=markup#l99

And step through the code? It might fall through to the catch block and java 8 
code.

Uwe

-----
Uwe Schindler
Achterdiek 19, D-28357 Bremen
https://www.thetaphi.de
eMail: u...@thetaphi.de

> -----Original Message-----
> From: Uwe Schindler <uschind...@pangaea.de>
> Sent: Friday, August 7, 2020 5:06 PM
> To: 'Andreas Beeker' <kiwiwi...@apache.org>; uschind...@apache.org
> Cc: dev@poi.apache.org
> Subject: RE: Java 9+ modules / cleaner
> 
> Hi,
> 
> > I currently try to understand, how to call the Cleaner in Java 14 (or 9+)
> without
> > adding the --add-opens JVM options.
> 
> Yeah, your code won't work correctly with Java 9 at all. You may fix it with
> some opens, but still types of internal calsses changed, so its just risky
> (everything is subject to change).
> 
> > As you've worked on this in LUCENE-6989, you might have a few hints for me.
> 
> I think you can more or less copy the code from Lucene (use the branch_8x
> version, as Master requires Java 11, so has no Java 8 code anymore, see here:
> https://tinyurl.com/y47euqfg). The aproach in Lucene does NOT use Reflection
> at all, it works with Method Handles. The important thing is: Method handles
> are linked earyl, once you have built the final method handle to invoke the
> cleaner, you can call it without requesting any additional right (security
> manager). In addition you know beforehand if it works at all (it cannot throw
> extra reflective exceptions).
> 
> The main change in Java 9 is (and this is what's officially "supported" by
> OpenJDK developer): They added a new method to sun.misc.Unsafe (the legacy
> one), Unsafe#invokeCleaner(ByteBuffer). This class is still in java.base and 
> is
> open to public (if you know how to get the singleton) for the time being. To 
> get
> the singleton, you need reflection and the code must allow to do setAccessible
> on the getter, but once you have it, it's useable.
> 
> To unmap a Bytebuffer, Lucene creates a MethodHandle with some signature
> like "unmap(ByteBuffer b)" complete pre-configued on startup of class
> depending on Java version:
> - In Java 9 and above it uses reflection to get the Unsafe instance (this 
> requires
> security manager to allow it). Then it looks up the method
> "invokeCleaner(ByteBuffer) and binds it to the unsafe  singleton, the final
> methodhandle is casted to me "void unmap(ByteBuffer)"
> - In Java 8 and before it uses more or less the old approach by checking the
> private method to get the Cleaner instance. Finally it calls cleaner.clean(). 
> This
> can also be composed to a MethodHandle with exactly same signature (using
> the famous MethodHandle transformation and bindings, introducing some null
> checks). The result is also a methodhandle with signature "void
> unmap(ByteBuffer)".
> 
> Once all this is done, the methodhandle with platform independent signature
> can be called without any exception handling from any code, so be sure to keep
> it safe in private final fields fully internal to your implementaion 
> (otherwise it's
> a security issue).
> 
> > I've checked the Lucene implementation, but that code is similar to POIs
> > current implementation. [1]
> > As I don't see the Runable interface, I might look at the wrong branch.
> 
> That won't work. It's the same approach like the old one, just with other 
> class
> types. You cant work around the internal Cleaner interface. This is why
> sun.misc.Unsafe#invokeCleaner() was added.
> 
> > Any ideas?
> 
> See above. I'd copy the code from Lucene: It's early binding and failsafe, 
> once
> you got the MethodHandle. The approach should work with Java 7+. In Java 7
> there is one additional helper method needed for the methodHandle regarding
> the null check!
> 
> Java 8 is here: https://tinyurl.com/y47euqfg
> Hack for compatibility with Java 7 is here: https://tinyurl.com/y4drev3k (this
> adds a "compatibility method" to replace missing "Objects#nonNull(Object)",
> but it's identical otherwise; we added this to make Lucene 5.5 still 
> compatible
> with Java 9, long after support ended, because customers need this).
> 
> Uwe
> 
> > Best wishes,
> > Andi
> >
> >
> > [1]
> > https://github.com/apache/lucene-
> >
> solr/blob/master/lucene/core/src/java/org/apache/lucene/store/MMapDirecto
> > ry.java#L338
> > vs.
> >
> https://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/nio/Cle
> > anerUtil.java?view=markup#l91
> >
> > On 09.07.20 00:34, Andreas Beeker wrote:
> > > Hi Dominik,
> > >
> > > the goal is to have no --add-opens or similar jvm arguments. In this case 
> > > we
> > get the following exception:
> > >
> > >    [junit] java.lang.reflect.InaccessibleObjectException: Unable to make
> public
> > jdk.internal.ref.Cleaner java.nio.DirectByteBuffer.cleaner() accessible: 
> > module
> > java.base does not "opens java.nio" to module org.apache.poi.poi
> > >     [junit]     at
> >
> java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleO
> > bject.java:349)
> > >     [junit]     at
> >
> java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleO
> > bject.java:289)
> > >     [junit]     at
> > java.base/java.lang.reflect.Method.checkCanSetAccessible(Method.java:196)
> > >     [junit]     at
> > java.base/java.lang.reflect.Method.setAccessible(Method.java:190)
> > >     [junit]     at
> >
> org.apache.poi.poi/org.apache.poi.poifs.nio.CleanerUtil.unmapHackImpl(Cleane
> > rUtil.java:116)
> > >     [junit]     at
> >
> java.base/java.security.AccessController.doPrivileged(AccessController.java:312
> > )
> > >     [junit]     at
> >
> org.apache.poi.poi/org.apache.poi.poifs.nio.CleanerUtil.<clinit>(CleanerUtil.jav
> > a:77)
> > >     [junit]     at
> >
> org.apache.poi.poi/org.apache.poi.poifs.nio.FileBackedDataSource.unmap(FileB
> > ackedDataSource.java:189)
> > >     [junit]     at
> >
> org.apache.poi.poi/org.apache.poi.poifs.nio.FileBackedDataSource.lambda$clos
> > e$0(FileBackedDataSource.java:162)
> > >     [junit]     at
> > java.base/java.util.IdentityHashMap.forEach(IdentityHashMap.java:1356)
> > >     [junit]     at
> >
> org.apache.poi.poi/org.apache.poi.poifs.nio.FileBackedDataSource.close(FileBac
> > kedDataSource.java:162)
> > >     [junit]     at
> >
> org.apache.poi.poi/org.apache.poi.poifs.filesystem.POIFSFileSystem.close(POIFS
> > FileSystem.java:764)
> > >     [junit]     at
> >
> org.apache.poi.poi/org.apache.poi.hpsf.basic.TestWrite.inPlacePOIFSWrite(Test
> > Write.java:539)
> > >
> > > If we use the Runnable aproach mentioned in the lucene bug, this should
> > work again.
> > >
> > > In the meantime I had to move a few sources from ooxml to main
> > (crypto.agile) and we need to find a way, e.g. using multi release classes, 
> > for
> > our WorkbookFactory, as with JIgsaw the poi main module can't reflect into
> > ooxml anymore. This was also a reason for moving the agile crypto into poi
> > main and removing the use XmlBeans schemas there.
> > >
> > > Best wishes,
> > > Andi
> > >
> > >
> > > On 07.07.20 18:00, Dominik Stadler wrote:
> > >> Hi,
> > >>
> > >> Sorry for replying late here, not sure if you already did these changes,
> > >> but the code in CleanerUtil tries to handle this gracefully with not
> > >> cleaning on JDKs which do not support this.
> > >>
> > >> There should be no compile-time dependency on any unsafe object, during
> > >> runtime we try to get a cleaner and simply not unmap buffers cleanly if
> not
> > >> possible for some reason.
> > >>
> > >> Which new problem do you see with this approach when using the JDK
> > module
> > >> system?
> > >>
> > >> Thanks... Dominik.
> > >>
> > >> On Mon, Jun 29, 2020 at 10:36 PM Andreas Beeker
> > <kiwiwi...@apache.org>
> > >> wrote:
> > >>
> > >>> Hi *,
> > >>>
> > >>> I'm facing the same problem as described in
> > >>> https://issues.apache.org/jira/browse/LUCENE-6989
> > >>>
> > >>> Is it ok for you, if I get our build more or less to run with the module
> > >>> path (instead of the classpath) when running in a JDK 9+ and later try 
> > >>> to
> > >>> fix the above Cleaner problem?
> > >>>
> > >>> I simply would like to focus on one issue now and as we a have
> > >>> multi-release jars after my commit, a JDK dependent solution shouldn't
> be
> > a
> > >>> problem anymore.
> > >>>
> > >>> Andi
> > >>>
> > >>>
> > >>>
> > >
> > >
> > > ---------------------------------------------------------------------
> > > To unsubscribe, e-mail: dev-unsubscr...@poi.apache.org
> > > For additional commands, e-mail: dev-h...@poi.apache.org
> > >
> >
> 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscr...@poi.apache.org
> For additional commands, e-mail: dev-h...@poi.apache.org


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

Reply via email to