Hi Alan,

we understand all this. But what you say is also not true. I started a second 
approach to fix the issue by using canAccess() and also checking the module 
stuff. For that I executed the following code on the Groovy unnamed module:

import org.codehaus.groovy.reflection.CachedClass;
String.getClass().getModule().isOpen(CachedClass.class.getPackage().getName(), 
CachedClass.class.getModule());

This returned false, so the java.base module is not open to the package and 
code hosting Groovy's CachedClass! But setAccessible still works with a warning.

If I do the same using another class from Groovy's own unnamed module, it 
returns true (as expected). If I call the same with a test of StringBuilder 
instead of CachedClass it returns true. If I try to access sun.misc.Unsafe that 
way, it works (as expected, because its declared as "open" in module descriptor 
- for good reasons, also if you don't permit illegal accesses).

So the module is definitely not "offically open" to the Groovy/unnamed module 
according to its metadata in java.lang.Module!

Because of this, many people were under the impression that the "open" hack 
only applied to the "old" setAccessible API, but new Java 9 APIs would behave 
in the new way. Because of this I understood Mark Reinhold's original proposal 
mail like this: old-style setAccessible still works with warning, all new APIs 
(trySetAccessible and Module metadata still say "the computer says no!"). 
Actually only the module metadata return the correct thing, trySetAccessible 
behaves like the old setAccessible.

So what we need to fix the issue: Give us an API that we can ask "is access 
possible" if I respect the module system and the module metadata?

I hacked this in a second attempt to solve Groovy's issue by using the above 
module metadata. Whenever it figures out that a class returns false for above's 
call, it does not even try to call setAccessible. See the code here:

https://goo.gl/JnrNyH

This works but the problem is that it is then hard to figure out which methods 
you can still call without setAccessible. With trySetAccessible or canAccess 
this would be fine. The problem for Groovy with canAccess() is that you need an 
instance, which is not available at the time of the check. Why is this? Why do 
I need an instance for canAccess() checks? I have the feeling because it could 
be a subclass of the reflected class you try the method call on, right?

Uwe

-----
Uwe Schindler
uschind...@apache.org 
ASF Member, Apache Lucene PMC / Committer
Bremen, Germany
http://lucene.apache.org/

> -----Original Message-----
> From: jigsaw-dev [mailto:jigsaw-dev-boun...@openjdk.java.net] On Behalf
> Of Alan Bateman
> Sent: Monday, July 10, 2017 11:56 AM
> To: Cédric Champeau <cedric.champ...@gmail.com>
> Cc: jigsaw-dev <jigsaw-dev@openjdk.java.net>
> Subject: Re: trySetAccessible​
> 
> On 10/07/2017 09:49, Cédric Champeau wrote:
> > I second Uwe's comment here: I was surprised as well, I expected the
> > semantics of `trySetAccessible` to be: "let me know if I can do this,
> > respecting the semantics of modules, and if not, return false"
> For the example, trySetAccessible succeeds (returns `true`) because
> `java.lang` is open.  If you run with `--illegal-access=deny` then
> `java.lang` will not be opened and trySetAccessible should return `false`.
> 
> -Alan

Reply via email to