Lambda class names no longer reported when listening for JVMTI_EVENT_CLASS_FILE_LOAD events

Frost, Gary Gary.Frost at amd.com
Thu Jan 23 16:11:15 PST 2014


Hey John


Thanks for the notes.  I will amend my code to use the hashcode this will save me from just stripping the  '/XXXXX' from the name and searching. :) which was my first hack around, which works just fine until I have a name collision.   I guess this works for my test cases because I control the 'horizontal and the vertical' ;) 

Two questions remain. 
1) Why does the reflected name (Class.getName()) include the /XXXXX suffix, yet the name in the class file itself remain undecorated.  This is what tripped me up. 
2) Why would we choose to no longer send the name (either /XXXXX decorated or not) to JVMTI agents (and I presume JavaAgents)..

I understand that we are driving pretty close to some spinning knives by getting our bytecode this way, and probably should not be even attempting to do this. 

How about the JVM providing a helper for this...  I note that Graal also has a mechanism for extracting bytes for a given class/method, in their case they can rely on their 'more intimate relationship' with hotspot. 

Maybe we could consider.....

Unsafe.getClassBytes(Class clazz); 

Gary

-----Original Message-----
From: John Rose [mailto:john.r.rose at oracle.com] 
Sent: Thursday, January 23, 2014 5:48 PM
To: Frost, Gary
Cc: Brian Goetz; lambda-dev at openjdk.java.net
Subject: Re: Lambda class names no longer reported when listening for JVMTI_EVENT_CLASS_FILE_LOAD events

On Jan 22, 2014, at 4:05 PM, "Frost, Gary" <Gary.Frost at amd.com> wrote:

> Hey Brian
> 
> After a bit of poking around I notice that if I turn on 
> 
> -verbose
> 
> The JVM reports loading the class I am interested in. 
> 
> I also noticed that the classes are passed to the JVMTI callback handler,  however the name is no longer passed, instead we seem to be passing NULL. 
> 
> Of course I have the bytes to the class being passed to my JVMTI handler ;) so when I dive into the classbytes I can indeed match the classname (sort of - see below). 
> 
> It looks like we are still passing the classbytes, we just chose to not pass the name.  Seemingly to make life a littl harder ;) for us Aparapi folk.
> 
> BTW I do note that there is some other  naming weirdness.  
> 
> These classes used to be called something like 
> 
> mypackage.MyClass$$lambda$1
> 
> Now the reflected classname of the implementation of IntConsumer (the lambda I am trying to get bytes for) is now 
> 
> mypackage.MyClass$$Lambda$1/XXXXX (where XXXXX is some 5 digit integer)
> 
> Whereas if I extract the name of the class from the bytes of the class the name is still 
> 
> mypackage.MyClass$$lambda$1
> 
> So whoever is composing this synthetic named class, seems to be encoding a different name in the class, than the name itself.  That seems scary.

Background on anonymous classes:

They are a private feature of the HotSpot JVM implementation.  Naturally, compilers and other tightly-coupled tools have to know about them.

They don't have names, at least in the sense of something you could use to look up via a class loader.  What names they display are (as you see) derived from their bytecodes, but they do not function as regular class names.

Specifically, if someone tries to use the supposed name of an anonymous class with Class.forName or ClassLoader.loadClass, the result will be ClassNotFoundException.

The mangled suffix /XXXXX on Class.getName string provides an extra hint as to what is wrong.  (The XXXXX value happens to be the class's hash code, which makes it easier to distinguish classes with the same supposed name.)  Since slash '/' is an illegal element of class names, there's no ambiguity about how the name got that way.

HTH

- John

> Gary
> 
> ________________________________________
> From: Brian Goetz [brian.goetz at oracle.com]
> Sent: Thursday, January 23, 2014 7:48 AM
> To: Frost, Gary
> Cc: lambda-dev at openjdk.java.net
> Subject: Re: Lambda class names no longer reported when listening for JVMTI_EVENT_CLASS_FILE_LOAD events
> 
> Yes.  We moved to "anonymous classes" (in the sense of Unsafe.defineAnonymousClass, not anonymous inner classes), for reasons of both security and performance.  This is an unfortunate side effect.
> 
> On Jan 22, 2014, at 5:33 PM, Frost, Gary wrote:
> 
>> Not sure when this change came about but I just started using
>> 
>> java version "1.8.0-ea"
>> Java(TM) SE Runtime Environment (build 1.8.0-ea-b124)
>> 
>> I noticed that the JVMTI agent I use to  listen for JVMTI_EVENT_CLASS_FILE_LOAD events is no longer seeing events for the dynamically create classes created to encapsulate 'captured' args.  Or possibly the class events are triggeted, but the 'name' is NULL. I am seeing an increase in the number of a events reported NULL as the name.
>> 
>> The Aparapi project listens for these events so we can determine the captured args for a given lambda.  These are the synthetic classes created on the fly by the method handle factory.
>> 
>> This had been working fine until recently.  Is there a reason we would stop generating  these, or is this just a regression?
>> 
>> Gary
>> 
> 
> 
> 
> 





More information about the lambda-dev mailing list