RFR 8145964: NoClassDefFound error in transforming lambdas

Daniel D. Daugherty daniel.daugherty at oracle.com
Thu Aug 18 02:01:16 UTC 2016


On 8/16/16 7:05 PM, David Holmes wrote:
> Hi Dan,
>
> This is going somewhat OT but should probably be discussed somewhere:
>
> > When an agent acquires can_redefine_any_class or
> > can_retransform_any_class, it is telling the VM that it plans to use
> > redefine classes or class transformation on as many classes as possible
> > so it would be a good idea to disable some optimizations like sharing.
>
> That is very interesting but there is absolutely nothing in the JVM TI 
> specification that I can see that even alludes to such a meaning. That 
> is a flaw in the spec.

Probably because no one could figure out a way to say something like:

- start with acquiring can_redefine_classes and calling IsModifiableClass()
   to see if your target class can be redefined
- if IsModifiableClass() returns false for some class you think you
   are interested in, then acquire can_redefine_any_class and try
   IsModifiableClass() class again
- and by the way, you might have to restart the VM in order to
   acquire can_redefine_any_class because it might not be acquirable
   in the live phase with the JVM you're using
- in fact, you might only be able to acquire can_redefine_classes
   before the live phase with the JVM you're using so late attach
   redefine classes won't work for you...

without sounding completely insane. :-)

As far as I've heard, agent writers acquire or try to acquire
can_redefine_classes and can_redefine_any_class as early as
possible just to avoid the insanity. As you can imagine, the
different folks on the JSR-163 team did not want to lock in
when some of the capabilities had to be acquired to a specific
phase...


> I also note that the spec is very clear that implementations of JVM TI 
> can impose their own restrictions on how capabilities can be applied, 
> yet there seems to be absolutely no documentation of what those 
> restrictions may be in our implementation.

I think there is supposed to be a set of "implementation notes" to
accompany a vendors implementation of JVM/TI that spells out that
vendor's specific implementation defined choices. For example, a
vendor doesn't haven't to support can_redefine_any_class, but that
has to be stated in the vendor's documentation about how JVM/TI
is implemented in their VM.

The docs we always quote are the JVM/TI spec (JSR-163). I don't
think I've ever read the HotSpot specific docs that go with claiming
conformance to the JVM/TI spec... I have vague memories about being
asked some questions about which capabilities we support, but that
was so very long ago...


> There is no way for anyone writing an agent to know a-priori whether 
> they need the "any" capability or not!

Yes that is true so most tool vendors try to acquire it any-way (pun 
intended).

Dan


>
> There's also an issue with the description in "Class File Load Hook" 
> but I'll take that up in response to Coleen's actual changes.
>
> Thanks,
> David
>
> On 16/08/2016 10:38 PM, Daniel D. Daugherty wrote:
>> Hi David,
>>
>> Need to chime in on a couple of parts from earlier in the thread.
>>
>>
>> On 8/14/16 10:05 PM, David Holmes wrote:
>>> Hi Dan,
>>>
>>> On 15/08/2016 12:20 PM, Daniel D. Daugherty wrote:
>>
>> <snip>
>>
>>>
>>>> There are various places that refer to can_redefine_any_class. Those
>>>> places
>>>> also need updating. Here's the one from RedefineClasses:
>>>>
>>>>> can_redefine_any_class    Can modify (retransform or redefine) any
>>>> non-primitive
>>>>>                           non-array class. See IsModifiableClass.
>>>>
>>>> Should probably be changed to something like:
>>>>
>>>> can_redefine_any_class    Can modify (retransform or redefine) any 
>>>> class
>>>> except for
>>>>                           a few specific classes. See 
>>>> IsModifiableClass
>>>> for the classes
>>>>                           that cannot be modified.
>>>
>>> <sigh> This is so frustrating. Why even bother with the notion of
>>> IsModifiableClass (which suggests any class might be non-modifiable
>>> under some circumstances) when it is then completely undermined by the
>>> can_redefine_any_class capability? If the intent was that only
>>> primitives and arrays are ever non-modifiable then that should have
>>> simply been listed in the spec for RedefineClasses and
>>> restransformClasses, instead of introducing IsModifiableClass.
>>> Otherwise can_redefine_any_class should simply refer to
>>> IsModifiableClass.
>>
>> Acquiring a capability is how an agent tells the VM what it plans to do.
>> When an agent acquires can_redefine_classes or can_retransform_classes,
>> it is telling the VM that it plans to use redefine classes or class
>> tranformation. When an agent acquires can_redefine_any_class or
>> can_retransform_any_class, it is telling the VM that it plans to use
>> redefine classes or class transformation on as many classes as possible
>> so it would be a good idea to disable some optimizations like sharing.
>>
>> A properly written agent will check possible target classes with
>> IsModifiableClass() before attempting redefine classes regardless of
>> whether the agent has acquired just can_redefine_classes or both
>> can_redefine_classes and can_redefine_any_class. This is similarly
>> true for class transformation and the can_retransform_classes and
>> can_retransform_any_class capabilities.
>>
>> We should probably update the wording for all four capabilities to
>> refer to IsModifiableClass() so that we can avoid having the same
>> wording in multiple places.
>>
>>
>> <snip>
>>
>>> The only thing that needs fixing in my opinion is the definition of
>>> can_redefine_any_class to not refer to primitives or arrays but simply
>>> to any class for which IsModifiableClass returns true!
>>
>> Yup. That's where we should go, but we should do it for all four
>> capabilities.
>>
>>
>>>
>>> can_redefine_any_class is really puzzling if you consider
>>> can_redefine_classes. It is far from clear to me what set of classes
>>> can_redefine_any_class gives access to that can_redefine_classes does
>>> not ??? What purpose do two capabilities serve here?
>>
>> can_redefine_classes and can_retransform_classes are needed if you
>> are going to redefine classes or transform classes at all. The "any"
>> capabilities are provided as a way to indicate that your agent
>> intends to redefine or transform as many classes as possible
>> including those that might normally have other optimizations applied
>> to them, e.g., sharing.
>>
>> Dan
>>



More information about the hotspot-dev mailing list