[sealed] Runtime checking of PermittedSubtypes
daniel.smith at oracle.com
Wed Apr 22 19:38:31 UTC 2020
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?
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