RFR: 8220607 Draft JEP: Hidden Classes

Kasper Nielsen kasperni at gmail.com
Fri Dec 6 23:34:13 UTC 2019


On Fri, 6 Dec 2019 at 22:22, Mandy Chung <mandy.chung at oracle.com> wrote:
>
>
>
> On 12/6/19 12:09 PM, Kasper Nielsen wrote:
> > On Thu, 5 Dec 2019 at 01:13, <(unknown sender)> wrote:
> >> Draft JEP:
> >>   ? https://bugs.openjdk.java.net/browse/JDK-8220607
> > Looks good, one quick question though. Is there any reason for the asymmetry
> > with Lookup.defineClass()? defineHiddenClass() takes a boolean initialize
> > parameter while defineClass() does not.
>
> Another asymmetry between Lookup::defineClass and defineHiddenClass is
> the return value, Class vs Lookup.

Right, I was merely questioning which situations you would need to initialize
a hidden class, but not a "normal" class. I think of the use cases for
Lookup::defineHiddenClass as a subset of those for Lookup::defineClass

> It's trivial to get the class from a Lookup object but we can't go the
> other way. If a framework wants to get Lookup from a hidden class it
> just defines (e.g. get a MethodHandle and invoke), if dHC returned a
> Class, the hidden class had to provide an entry point to return its
> Lookup object.  Such entry point has to be accessible to the framework
> but it has to be cautious in leaking its full-power Lookup.

At first glance, I was a bit puzzled by the return type, but it's
quite a clever
solution.

> I have considered adding Lookup::defineClassAsLookup(byte[] bytes,
> boolean initialize).   Lookup::defineClass was added in JDK 9.   I
> haven't seen any request to initialize the class.   So I think it can be
> done as a separate enhancement.  I will file a JBS issue.

I don't think Lookup::defineClassAsLookup is enough, something like
Lookup::ensureClassInitialized(Class<?> clazz) (requiring MODULE_ACCESS?)
is still needed in my opinion.

Again since we don't have any way of expressing that a certain member
is only accessible within a single module. I have had to implement something
similar to jdk.internal.misc.SharedSecrets in a couple of libraries.

public static JavaLangModuleAccess getJavaLangModuleAccess() {
    if (javaLangModuleAccess == null) {
        unsafe.ensureClassInitialized(ModuleDescriptor.class);
    }
    return javaLangModuleAccess;
}

Unfortunately, without some kind of Lookup::ensureClassInitialized
method, you will still need to resort to Class.forName outside of the JDK.
I know this is quite a specialized use case, but I'm sure other people will
run into the issue as more and more libraries are better encapsulated.

Thanks
  Kasper


More information about the valhalla-dev mailing list