On 17/01/2018 12:18, Rony G. Flatscher wrote:
:
The reflection logic in the bridge is (simplified) as follows:
* use the object's 'o' class and look up its declared methods or
fields, analyze further, if member is 'public', otherwise
o iterate over all of its superclasses looking up in each class
all declared methods or fields, analyze further, if member is
'public' *or* 'protected' (looking up a superclass 'protected'
is regarded to be 'public' for the subclass) and, if a
matching member is found, carry out the operation (in this
case a Field.get()) and return its value
This way it is assured that the users of the bridge are never able to
get at private or package private members (nor that they are able to
invoke a protected member in the object's type itself).
Accessibility has been significantly upgraded in Java SE 9. "public"
used to imply accessible to everyone, now we have "public to everyone",
"public to friend modules" or "public within a module". If you want the
above logic to work with modules then it will need to be updated to
handle classes in named modules. It will essentially amount to
overhauling the above to find the accessible members rather the public
members (in public classes).
BTW: On protected members then I assume they have never been accessible
to the bridge, maybe the bridge is using setAccessible to suppress the
access checks for those cases?
---
The current implementation seems to do the following: it checks
whether a class is from anĀ exported package, if not it creates an
exception. If the class is exported it then checks whether the
reflected member is public, if not it creates an exception.
What I would have expected is this: everything like the current
implementation, but in the second step, if the member is not public,
check whether the object's class for which the reflection takes place
is a subclass of the class that is being checked and if so, allow
protected members to be accessed as well. Hence: in the example
presented, the packages 'mtest1' and 'mtest3' are exported, the class
'mtest3.Class03A' extends 'mtest2.Class02A' which extends
'mtest1.Class01A'. Therefore the object of type 'mtest3.Class03A' is a
subclass of 'mtest1.Class01A', hence as 'mtest1' is exported all
'mtest1.Class01A' public *and* protected members should be accessible
to the object of the subtype 'mtest3.Class03A' via reflection in Java
9 as well.
You should find that the protected members are accessible in the
sub-class (mtest3.Class03A in this case). They won't be accessible to
the bridge code of course (as least not without some kind of rights
delegation as John mentioned).
-Alan