On 16.01.2018 10:18, Alan Bateman wrote:
> On 15/01/2018 20:56, Rony G. Flatscher wrote:
>> :
>>
>> So the question is, how can I reflectively access "mtest1.Class01A" static 
>> protected field
>> "myClassName" from "mtest3.Class03a" in Java 9?
>>
> The scenario in your mail is complicated but if I read it correctly then I 
> would expect this code
> in mtest3.Class03A (mod_C) to work:
> Class.forName("mtest1.Class01A").getDeclaredField("myClassName").get(null);
The problem here is, that no code from any of the modules is doing the 
reflection. Rather the
reflection comes from packages on the class path, hence from the unnamed module.

> I can't tell if the code in the unnamed module extends mtest1.Class01A or 
> not. If it does then the
> same code should work, if it's not a sub-class then you should see 
> IllegalAccessException being
> thrown.
The excercise here is as follows:

  * there are classes in "mod_A" which get extended in "mod_B" and once more 
extended in "mod_C". 
  * Hence "mod_B" requires "mod_A", and "mod_C" requires "mod_B", where "mod_B" 
exports to "mod_C" only
  * These are the two chains of class extensions, one (mtest1.Class01A) defines 
an abstract public
    class with protected members, one (mtest1.Class01B) defines a public class 
with public members,
    hence:
      o one chain is: 
          + in "mod_A" there is the class "abstract public class 
mtest1.Class01A", which contains a
            protected static field named "myClassName",
          + in "mod_B" there is the class "public class Class02A extends 
mtest1.Class01A", has no
            static field named "myClassName",
          + in "mod_C" there is the class "publi class Class03A extends 
mtest2.Class02A", has no
            static field named "myClassName.
      o another chain is:
          + in "mod_A" there is the class "abstract public class 
mtest1.Class01B", which contains a
            protected static field named "myClassName",
          + in "mod_B" there is the class "public class Class02B extends 
mtest1.Class01B", has no
            static field named "myClassName",
          + in "mod_C" there is the class "public class Class03B extends 
mtest2.Class02B", has no
            static field named "myClassName.

Two scenarios, one works, one causes the "IllegalAccessException":

  * works: creating an instance of "mtest3.Class03B" reflectively and then 
getting the value of the
    public static field "myClassName" in "mtest1.Class01B", works reflectively!

  * "IllegalAccessException": creating an instance of "mtest3.Class03A" 
reflectively and then
    getting the value of the public static field "myClassName" in 
"mtest1.Class01A", causes the
    "IllegalAccessException";

      o Interestingly,
          + the first error message is: "java.lang.IllegalAccessException: class
            org.rexxla.bsf.engines.rexx.RexxReflectJava9 cannot access a member 
of class
            mtest1.Class01A (in module mod_A) with modifiers "protected static"

          + in the catch block then trying a "setAccessible(true)" yields 
another
            "IllegalAccessException" now with the following error message:
            "java.lang.reflect.InaccessibleObjectException: Unable to make 
field protected static
            java.lang.String mtest1.Class01A.myClassName accessible: module 
mod_A does not "opens"
            mtest1" to unnamed module @33b37288"

> Your traces show InaccessibleObjectException being thrown so I think you are 
> attempting to call
> setAccessible(true) to suppress the access check. You can't do on that 
> protected members when the
> package is not open for deep reflection. In the example, mod_A would need to 
> `opens mtest1` to
> allow this. 
And that is exactly the point. "mtest1.Class01A" is a superclass of 
"mtest3.Class03A". Therefore the
protected members in the superclass "mtest1.Class01A" are public for its 
subclasses like
"mtest3.Class03A".

This is a very basic and important property of the Java language.

Therefore I assume that this is a bug in the current implementation of Java 9, 
but want to know for
sure.

---

I asked this very question ("are protected members in superclasses regarded to 
be public for
subclasses") almost nine months ago and it was agreed that "protected" in 
superclasses become
effectively "public" for subclasses in Java 9 as well, so it was clear that 
when adjusting the
bridge to Java 9 everything would work as in the past for the users. [For the 
past 17 years I have
always adhered to these Java semantics in the Rexx/ooRexx-Java bridge, users of 
the bridge have only
been able to access public classes and public members and protected classes and 
protected members of
superclasses. There has never been a need for any deep reflection (nor "desire" 
to do so) as package
private and private members have to be respected to be "private".]

---rony


Reply via email to