See also here:
https://blogs.oracle.com/java/get-ready-jdk9

Sorry for not understanding the whole problem (module system usage instaed of 
classpath). Your code is perfectly valid and works with Java 9, it's just broken

I still wonder why you get this Exception at all. It should be swallowed by the 
last try/catch block and saved as a warning for "UNMAP_UNSUPPORTED". Or did you 
hack the code to get the full stack trace?

Uwe

-----
Uwe Schindler
[email protected] 
ASF Member, Apache Lucene PMC / Committer
Bremen, Germany
https://lucene.apache.org/

> -----Original Message-----
> From: Uwe Schindler <[email protected]>
> Sent: Friday, August 7, 2020 6:16 PM
> To: 'POI Developers List' <[email protected]>; 'Andreas Beeker'
> <[email protected]>
> Subject: RE: Java 9+ modules / cleaner
> 
> To confirm: If you use POI as a JAR on classpath it will work without
> modifications: Try it out.
> For the module system you need to import jdk.unsupported module.
> 
> This is hard to figure out, the stack trace gave me the hint. It’s a HUGE
> difference if you put a JAR file on classpath (there it works) or on 
> modulepath
> (won't work without importing jdk.unsupported).
> 
> In both cases, if everything is declared correctly in JAR file no 
> exports/imports
> or command line options are needed.
> 
> Lucene does not support Modules at all, so it's no issue for us.
> 
> Uwe
> 
> -----
> Uwe Schindler
> [email protected]
> ASF Member, Apache Lucene PMC / Committer
> Bremen, Germany
> https://lucene.apache.org/
> 
> > -----Original Message-----
> > From: Uwe Schindler <[email protected]>
> > Sent: Friday, August 7, 2020 6:12 PM
> > To: 'POI Developers List' <[email protected]>; 'Andreas Beeker'
> > <[email protected]>
> > Subject: RE: Java 9+ modules / cleaner
> >
> > Ah I think I know!The code is fine, it's just how you use it.
> >
> > Could it be that you are compiling this as a module and also use it as a
> module
> > (the stack trace implies this)? If you use the code as a "real" module, you 
> > have
> > to import explicitely in your module-info the "jdk.unsupported" module,
> > otherwise you won't get access to sun.misc. You may need to add this to the
> > auto-module descriptor or module-info.java.
> >
> > This must not only be done in tests, Your JAR file MUST declare that it 
> > needs
> > "jdk.unsupported" module. If it does not do this CleanerUtil is useless. In
> > contrast to the classpath approach, where there is a default set of modules
> > enabled, in a modulepath you only get what you declare - very simple.
> >
> > In short:
> > You code fails, because the Class.forName() in the Java 9 code will not find
> > "sun.misc.Unsafe", because its shielded by the module system. Because of
> this
> > it falls back to the Java 8 code, which won't work at all (causing the
> > exceptions).
> >
> > Uwe
> >
> > -----
> > Uwe Schindler
> > [email protected]
> > ASF Member, Apache Lucene PMC / Committer
> > Bremen, Germany
> > https://lucene.apache.org/
> >
> > > -----Original Message-----
> > > From: Uwe Schindler <[email protected]>
> > > Sent: Friday, August 7, 2020 5:20 PM
> > > To: 'POI Developers List' <[email protected]>; 'Andreas Beeker'
> > > <[email protected]>; [email protected]
> > > Subject: RE: Java 9+ modules / cleaner
> > >
> > > 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/Cle
> > > anerUtil.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: [email protected]
> > >
> > > > -----Original Message-----
> > > > From: Uwe Schindler <[email protected]>
> > > > Sent: Friday, August 7, 2020 5:06 PM
> > > > To: 'Andreas Beeker' <[email protected]>; [email protected]
> > > > Cc: [email protected]
> > > > 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
> > > > > <[email protected]>
> > > > > >> 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: [email protected]
> > > > > > For additional commands, e-mail: [email protected]
> > > > > >
> > > > >
> > > >
> > > >
> > > >
> > > > ---------------------------------------------------------------------
> > > > To unsubscribe, e-mail: [email protected]
> > > > For additional commands, e-mail: [email protected]
> >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: [email protected]
> > For additional commands, e-mail: [email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to