----- Mail original ----- > De: "daniel smith" <daniel.sm...@oracle.com> > À: "amber-spec-experts" <amber-spec-experts@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. Rémi