----- Mail original -----
> De: "Rony G. Flatscher" <rony.flatsc...@wu.ac.at>
> À: "Alan Bateman" <alan.bate...@oracle.com>, "jigsaw-dev" 
> <jigsaw-dev@openjdk.java.net>
> Envoyé: Mardi 13 Mars 2018 13:16:49
> Objet: Re: p example (Re: Reflection: how can one access public fields 
> (members) in a superclass ?

> Just to conclude this posting: first many thanks to Alan!
> 
> Alan's little nutshell example about how to use MethodHandles.Lookup and 
> employ
> MethodHandle s to
> invoke helped me a lot to get afloat with rewriting the reflection part for 
> the
> bindings also using
> MH. The new reflection mechanism has been implemented such that on Java 1.6/6
> and 1.7/7 it uses core
> reflection (on Java 1.7/7 MethodHandle only reflection runs in some errors 
> that
> cannot be
> circumvented, hence using core reflection) reflection with the need to do
> setAccessible(true) in
> quite a few places. The support for Java 1.8/8 and 9 can use both, core
> reflection (without a need
> for setAccessible() at all!) and MethodHandle reflection (with one case found 
> so
> far, that does not
> work on MH, but with core reflection).
> 
> The type of reflection that is being carried out is in all my use cases (my
> bridge intentionally has
> been only supporting public classes and public members) not really
> specific/relevant to jigsaw. Just
> wanted to point that out explicitly.
> 
> ---
> 
> The only grief I have at the moment is with the meaning of "public": "public"
> has become a homonym
> in jigsaw, introducing a *lot* of confusion into Java (one time "public" is
> public, another time
> "public" is not public).
> 
> This could be probably eased considerably IMHO, if there was a class Modifier
> introduced named
> "module" that would be set for reflective access to classes from non exported
> modules.

It already exists, but not at class level, 
you can open a module, or each package individually, in that case, 
setAccessible is allowed.

> 
> This would have at least the following benefits:
> 
> - communicating (and teaching!) about the publicness of a class can 
> immediately
> be clarified ("is
> the class truly public or does it reside in a non-exported module?"),

Teaching is not a big deal because you can teach package and module at the same 
time and say that it works like onions or russian dolls,
you have module access, class access and member access, by example, a public 
field is not really public if the class is not public and the package not 
exported.
If you take a look from the point of view of accessing a member (and not a 
class), things are regular at module level and class level.  

> 
> - also, programmatically it would be simple to learn whether a class object
> fetched reflectively is
> truly public or not by testing against the presence of such a "Module" 
> modifier
> bit at runtime in
> Java 9 or higher.

you can use Lookup.accessClass() [1].

> 
> ---rony

Rémi
[1] 
https://docs.oracle.com/javase/9/docs/api/java/lang/invoke/MethodHandles.Lookup.html#accessClass-java.lang.Class-

> 
> 
> On 24.01.2018 20:48, Alan Bateman wrote:
>> On 24/01/2018 15:42, Rony G. Flatscher wrote:
>>>
>>> OK, now add to this the following class that uses p.C2 objects to access 
>>> e.g.
>>> m() via it:
>>>
>>>     G:\xfer\java9modules\03-20180124-AlanBatmanP\p>type UseC2.java
>>>
>>>     public class UseC2
>>>     {
>>>         public static void main (String args[]) {
>>>             p.C2 o=new p.C2();
>>>             System.out.println("o="+o);
>>>             System.out.println("o.m()="+o.m());
>>>         }
>>>     }
>>>
>>> Compiling all three classes works.
>>>
>>> Running "UseC2" works and outputs:
>>>
>>>     G:\xfer\java9modules\03-20180124-AlanBatmanP\p>java -cp ".;.." UseC2
>>>     o=p.C2@66048bfd
>>>     o.m()=-1
>>>
>>> So it is possible to access m() via the p.C2 object from UseC2.
>> That's right and this is the reason for moving to the simpler example.
>>
>> To be absolutely sure then you should decompile C2.class to make sure that 
>> there
>> isn't a bridge
>> method calling C1's m2(). If you change m() to be final then that will keep 
>> the
>> bridge method from
>> complicating the picture.
>>
>> If you change UseC2 to use core reflection and you hit the issue because the
>> Method object you get
>> is p.C1.m(). Attempting to invoke this will fail with 
>> IllegalAccessException. In
>> your other mail
>> you show a code fragment where it catches exceptions and calls setAccessible 
>> -
>> I'll guess that
>> this may have been masking the issue in the Rexx bridge.
>>
>> For completeness then you may want to try out the new reflection API. I 
>> realize
>> you have to
>> compile to JDK 6 but I think you'll find it will work the same way as the
>> invokevirtual that o.m()
>> compiles to.
>>
>>     MethodHandles.Lookup lookup = MethodHandles.lookup();
>>     MethodType mt = MethodType.methodType(int.class);
>>     MethodHandle mh = lookup.findVirtual(p.C2.class, "m", mt);
>>     Object res = mh.invoke(o);
>>
> > -Alan

Reply via email to