Reflection: how does one access a protected member in a superclass reflectively?
Alan Bateman
Alan.Bateman at oracle.com
Tue Jan 16 15:03:29 UTC 2018
On 16/01/2018 13:50, Rony G. Flatscher wrote:
> 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",
>
If I read the earlier text correctly then Class01B.myClassName is public.
> + 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!
>
I assume the caller is org.rexxla.bsf.engines.rexx.RexxReflectJava9 on
the class path. Module mod_A exports mtest1, mtest1.Class1B is public,
code on the class path can reflect on Class1B's public members.
> * "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";
>
I think you mean "protected static".
> *
>
>
> 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"
>
This looks correct, RexxReflectJava9 is not a sub-class of
mtest1.Class01A so it can't expect to reflect on Class01A's protected
members.
> + 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"
>
The InaccessibleObjectException looks correct too.
> 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".
Do you have an issue here? If code is added to mod_C/mtest3.Class03A to
reflect on protected members of mod_A/mtest1.Class01A then I would
expect it to work. Furthermore, I would expect setAccessible(true) to
succeed on protected static members too (not instance members of course).
That said, the scenario that you've shown is code in RexxReflectJava9
doing the reflection. It's not in a sub-class of mtest1.Class01A so it
should not have any access to its protected members.
-Alan
More information about the jigsaw-dev
mailing list