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