getPermittedSubclasses() on j.l.rClass returning an array of ClassDesc

John Rose john.r.rose at
Sat May 9 21:26:32 UTC 2020

On May 9, 2020, at 2:00 PM, Remi Forax <forax at> wrote:
> ...
> This BTW is one of many reasons we want a symbolic linkage mode
> for indy and condy, in which the BSM is set to run on pre-resolved
> ConstantDesc data.
> I think it's worst, you want some type arguments to be already resolved and some not yet to be resolved.

We should talk more about this…  We can define a purely
symbolic, 100% non-resolving BSM if we choose.  The key
step there is choosing a single global BSM as the foundation,
with appropriate resolving and dispatching behavior,
including behaviors that cover the currently specified set.

And there are possible mixed options, where resolution is
minimized but not eliminated.

I think we can, if we choose, bring BSM-mediated call sites
and constants into conformance with the very lazy resolving
modes of the nominal bytecodes (get*, put*, invoke*, ldc/class).
IIRC you and Dan and I have all talked about bits of this.

I’ve thought about this more recently because of the sad problems
with bootstrapping an indy-based checkcast.  A purely symbolic
BSM mode would be executable without bootstrapping problems,
except for dependencies via ConstantDesc types.  As such it could
be executed AOT in jlink or javac, for Project Leyden.

> ...Here’s something very ugly we could do, FTR.  (I’m not
> fully comfortable with any of these choices.)  Make the
> new accessor @CallerSensitive (like Class::forName) and
> have it check accessibility.  If it throws, it throws away
> any partial information that might have been available.
> That’s how Core Reflection rolls.
> Yesterday, i was thinking exactly the same thing, I decide that it doesn't worth it because usually implementation classes leaks because getClass() is not caller sensitive.

Yeah, I considered that point, and decided put out the
proposal because of this:  A programmer can control leaking
of private classes by ensuring that *instances* of those classes
do not leak.  There is no such defense for reflection, which
doesn’t rely on reachability of instances. (And the nestmate
APIs make it worse, oops.)  So locking metadata reflection is
not made *completely* fruitless by Object::getClass.

Here’s a sort-of-happy thought:  If we add “species” as a refinement
of class, and getClass does not return a species, but rather the class
above the species, then programmers who are serious about metadata
hiding could lock down species even as the associated classes escape.
That would require (this is not so happy) an access check on a future
Object::getSpecies reflective call.  But maybe that would be the right
design.  It might even move us toward a day when getClass on a
lambda gives something completely benign, instead of today’s hidden

Pushing harder:  What would happen if getClass on a lambda returned
a representation of the type to which the lambda conforms, and no more?
(Usually, that’s a single interface.)  If not an interface, then a class which
is spun by the JVM, 1-1 with the required interface.  Under that are invisible
species, one per lambda implementation category.

— John
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the amber-spec-experts mailing list