p example (Re: Reflection: how can one access public fields (members) in a superclass ?

Rony G. Flatscher Rony.Flatscher at wu.ac.at
Tue Mar 13 12:16:49 UTC 2018


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.

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?"),

- 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.

---rony


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 at 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



More information about the jigsaw-dev mailing list