[sealed] Runtime checking of PermittedSubtypes

Remi Forax forax at univ-mlv.fr
Wed Apr 22 20:43:43 UTC 2020

----- Mail original -----
> De: "daniel smith" <daniel.smith at oracle.com>
> À: "amber-spec-experts" <amber-spec-experts at openjdk.java.net>
> Envoyé: Mercredi 22 Avril 2020 21:38:31
> Objet: [sealed] Runtime checking of PermittedSubtypes

> Iterating on the JVMS changes for sealed types, I've been refining the details
> of the runtime check.
> Two assertions, which I want to validate:
> - The run-time modules of a subclass and a sealed superclass must be the same.
> - The defining class loaders of a subclass and a sealed superclass must be the
> same.
> The first is a forced move, as discussed previously: the subclass and superclass
> must refer to each other, and mutual recursion is impossible between different
> modules (there are no module dependency loops).
> The second is implied by the first: "A run-time module is implicitly bound to
> exactly one class loader, by the semantics of defineModules." (JVMS 5.3.6)
> If this is true, then when we load the subclass, the superclass validation check
> should look like this:
> 1) If the superclass is ACC_FINAL, error.
> 2) If the superclass has a PermittedSubtypes attribute, then:
> 2a) If the superclass belongs to a different run-time module, error.
> 2b) If the superclass doesn't have the subclass's name in its PermittedSubtypes,
> error.
> [Would love to have a module expert weigh in on the following:]
> 2b doesn't need to load anything, because 2a has guaranteed that both classes
> have the same defining loader. (We do the same thing with nestmates.)
> I'm a little unsure about 2a, though, because I don't have a great grasp of how
> modules work—when I'm still deriving a class (JVMS 5.3.5), can I tell what my
> runtime module will be?

>From the class name which is qualified, you have the package name and from a package name and a classloader, you have the module.
A module knows all the packages inside itself, during the modules resolution, each module advertise all its packages, so when a classloader on a resulting configuration, it knows the Map<Package, Module>.
If the classloader doesn't find the module associated to a package, it means that it's a package from the classpath, so the package will be created lazily using the unamed module of the classloader.

> We could check for the same loader in 2a instead, but then there would still be
> a hole:
> - A class p1/Foo is loaded by loader L in module m1
> - A class p2/Bar is loaded by loader L in module m2
> - m1 requires m2
> - p1/Foo extends p2/Bar
> - p2/Bar has a PermittedSubtypes attribute that names "p1/Foo"
> - If we were to resolve "p1/Foo", we'd get a NCDFE (I think? Again, I'm hazy on
> modules.)
> Ideally, class p1/Foo should fail to load.


More information about the amber-spec-experts mailing list