getPermittedSubclasses() on j.l.rClass returning an array of ClassDesc
forax at univ-mlv.fr
forax at univ-mlv.fr
Sat May 9 15:44:40 UTC 2020
> De: "Brian Goetz" <brian.goetz at oracle.com>
> À: "Remi Forax" <forax at univ-mlv.fr>, "amber-spec-experts"
> <amber-spec-experts at openjdk.java.net>
> Cc: "joe darcy" <joe.darcy at oracle.com>, "Vicente Romero"
> <vicente.romero at oracle.com>
> Envoyé: Samedi 9 Mai 2020 16:53:11
> Objet: Re: getPermittedSubclasses() on j.l.rClass returning an array of
> ClassDesc
> It's not just that it is _inconvenient_ to return the Class, "because of class
> loading." It may not be _possible_, as the class may not be there, but we would
> still like to be able to reflect what the class says.
> So the choices are:
> - Don't make this information accessible at all
> - Return descriptor strings
> - Return ClassDesc
> Of the latter two, clearly ClassDesc is better than descriptor strings. (You
> could argue that we should go from array to List; this is an OK option but then
> the "for consistency" patrol will criticize it.)
What can help here is to consider how the VM uses the permitted subclasses, given that the reflection API is about information available at runtime.
Having the class not be there is not really an issue for getPermittedSubclasses() because the way the VM validate if a class is permitted or not, i.e. when the class is loaded, verified that the name is in the attribute if the attribute exists.
So removing the classes which does not exist at runtime from the array returned by getPermittedSubclasses() provides the exact same amount of information as the information that the VM use.
Moreover, it's not a new problem, getNestMembers() has exactly the same issue and nestmates have the same kind of lazy validation, the VM doesn't check nestmate attributes untile an access orccurs.
So piggybacking on what getNestMembers() do seems a good idea.
> I think a better question is: what do we expect people to DO with this
> information? That class C permits D doesn't confer anything about what any
> given user can do with D; D might be nonexistent, or inaccessible to some
> clients.
Being inaccessible should be rare here given that all the sealed subclasses are in the same module. You need a classloader that actively rejects the class.
> Or it might not have any members that are accessible to some client. So what
> would a client plan to do with the Class?
The main usages seems to be, annotations discovery at runtime (it's sad but that a story for another time) and bookeeping all possible implementations of a type, by example a deserialization library (jackson, hibernate, etc) can leverage getPermittedSubclasses() to get from a static type, by example the parameter type of a setter, all the possible implementations of that type (currently libraries ask the type to be annotated with the implementation classes).
Rémi
> On 5/8/2020 6:53 PM, Remi Forax wrote:
>> The current draft of the reflection API for the sealed keyword adds a method
>> getPermittedSubclasses() [1] to java.lang.Class.
>> I'm not fully sure that returning an array of ClassDesc is the right choice
>> here, mainly for two reasons,
>> 1/ it's weird to return an array of ClassDesc when all others similar methods
>> return an array of Class,
>> I know why a ClassDesc might be "better" because it avoid the class loading,
>> but it also means that now to fully understand java.lang.Class, people has to
>> understand how java.lang.constant works.
>> The java.lang.constant API was not designed for that, the first line of the
>> overview of this package talks about descriptors, constant pool and indy, not
>> something beginners should worry about.
>> 2/ returning a symbolic view (ClassDesc) instead of a Class is *very* error
>> prone from a user POV, to resolve a ClassDesc to a class, the user as to
>> provide a Lookup
>> and there is a good chance that users will pick the wrong ones. The number of
>> people that understand classloading and how Lookup works is < 10,
>> even experts struggle given the number of time the Lookup API as to be patched
>> in recent years. Returning a ClassDesc in this context is like asking a child
>> to read the serial number of a loaded gun.
>> Perhaps a way to mitigate that is to provide the code a user should use to get
>> the equivalent classes in the javadoc of getPermittedSubclasses().
>> cheers,
>> Rémi
>> [1] [ https://bugs.openjdk.java.net/browse/JDK-8244556 |
>> https://bugs.openjdk.java.net/browse/JDK-8244556 ]
More information about the amber-spec-observers
mailing list