On Tue, 1 Dec 2020 00:36:54 GMT, Mandy Chung <[email protected]> wrote:
>> The JVM method that returns the permitted subclasses (and interfaces) does
>> not weed out permitted subclasses based on the above module requirements.
>> It returns all the classes listed in the PermittedSubclasses attribute that
>> it is able to load.
>
> So it could also return a class listed in `PermittedSubclasses` attribute but
> not a subclass of this sealed class, right?
>
> The specification of `Class::getPermittedSubclasses` says:
>
>> Returns an array containing {@code Class} objects representing the direct
>> subclasses or direct implementation classes permitted to extend or direct
>> subinterfaces or subclasses permitted to extend or implement this class or
>> interface if it is sealed.
>
> I expect that `Class::getPermittedSubclasses` should do more work and return
> only the subclasses or subinterfaces permitted at runtime.
I was investigating a little today. One thing to note is that there is a
difference between the JLS and JVMS[1] restrictions - the JVMS restrictions
only require the classes to be in the same module, but they can be in any
package (even for an unnamed module).
Moreover, a lot of the constraints are checked automatically: e.g. consider
class api.Api in module "a", which permits impl.Impl in module "b", subtyping
Api. Loading of impl.Impl on behalf of getPermittedSubclasses() will fail
(because the two classes are in different modules). So impl.Impl will not be
included.
So far, it seems the only constraint that I think is not satisfied by this
implicit loading is that the permitted subclass is really a direct subtype of
the current class.
My proposal is to enhance the Java method with the direct subtype check (with a
possible future cleanup task to move the check to native, as is done for
getNestMembers()).
[1]
http://cr.openjdk.java.net/~gbierman/jep397/jep397-20201104/specs/sealed-classes-jvms.html#jvms-5.3.5
-------------
PR: https://git.openjdk.java.net/jdk/pull/1483