Reflection: how does one access a protected member in a superclass reflectively?

jeffrey kutcher jeffrey_kutcher at yahoo.com
Wed Jan 17 15:10:57 UTC 2018


 Disclaimer:
I don't have access to the full picture but wanted to throw this out there. Maybe it will be useful. Maybe you've already considered doing something like this and shot it down a long time ago. I don't know if there are show stoppers and I don't have the end goal in mind. However it seems like it might be a useful way to simplify what I've read so far. The following suggestion might untangle the web which appears to be growing though it may be too late to introduce.
Suggestion:
A closure might provide the plumbing you're looking for rather than using public/private/protected modifiers which seems to be gaining overloaded status. public/private/protected modifiers should go back to their original meaning and kept simple. A closure would allow classes by default, no or default access/authority/permission/security unless being owned by a container in which case would assume it's owner's access. This might eliminate the expanding access issues your finding and be more robust in the process, maybe even collapse the code. You'll have to provide an environment to accomplish this.
If a class "has a" or "is a" sub-class, the sub-class would take on the access of the parent class until such time as it deferred that access for more specific purposes. If not, any "has a" or "is a" sub-class would assume the role of its owner.
"has a" and "is a" sub-classes would have to reference their owner's environment to gain access permission otherwise no (or default) access would be granted.
Coming up with the right convention should prove to be elegant and introduce little to no overhead.
    On Wednesday, January 17, 2018, 7:14:23 AM CST, Alan Bateman <Alan.Bateman at oracle.com> wrote:  
 
 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  


More information about the jigsaw-dev mailing list