Reflection: how does one access a protected member in a superclass reflectively?
Rony G. Flatscher
Rony.Flatscher at wu.ac.at
Tue Jan 16 18:37:57 UTC 2018
On 16.01.2018 16:03, Alan Bateman wrote:
> 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.
Yes.
>
>> + 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".
Yes, sorry.
>
>> *
>>
>>
>>
>> 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.
Well that is probably the core of the problem: who needs to be the subclass, the reflector or the
object to be reflected upon (whose inheritance tree is being walked up towards the root class, and
if public or protected members are found reflectively accessed)?
Or conceptually: the "mtest3.Class03A object" is clearly from a subclass of "mtest1.Class01A". Why
should it then not be allowed to access the public and protected members in the superclass
"mtest1.Class01A" via reflection on behalf of the "mtest3.Class03A object", which gets supplied in
the reflective access and which can be used to check whether the access would be legal or not?
---rony
More information about the jigsaw-dev
mailing list