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