JDK-6328000 : class redefinition failed "method deleted"
  • Type: Bug
  • Component: hotspot
  • Sub-Component: jvmti
  • Affected Version: 6
  • Priority: P2
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2005-09-23
  • Updated: 2010-05-10
  • Resolved: 2005-12-07
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other JDK 6
5.0u8Fixed 6 b63Fixed
Related Reports
Relates :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.6.0-ea"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.6.0-ea-b52)
Java HotSpot(TM) Client VM (build 1.6.0-ea-b52, mixed mode, sharing)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows 2000 [Version 5.00.2195]

A DESCRIPTION OF THE PROBLEM :
For some classes, a call to retransformClasses fails with the following error, even when no transformers are present.

java.lang.UnsupportedOperationException: class redefinition failed: attempted to delete a method


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile the class referenced below and package it as a java.lang.instrument Java agent with the provided manifest.  Run the Java2D demo shipped with the 1.6.0_b52 jdk, using this java Agent:

java -javaagent:TestAgent.jar -jar Java2Demo.jar


EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
No UnsupportedOperationException errors during the retransformClasses calls since no transformers are present.

ACTUAL -
Two java.lang.UnsupportedOperationException errors occurred, even though no transformers were present.

ERROR MESSAGES/STACK TRACES THAT OCCUR :
Retransform failed for class java2d.demos.Paint.TextureAnim$AnimVal
java.lang.UnsupportedOperationException: class redefinition failed: attempted to delete a method
        at sun.instrument.InstrumentationImpl.retransformClasses0(Native Method)
        at sun.instrument.InstrumentationImpl.retransformClasses(InstrumentationImpl.java:116)
        at TestAgent.reloadClasses(TestAgent.java:47)
        at TestAgent.run(TestAgent.java:31)
        at java.lang.Thread.run(Thread.java:611)
Retransform failed for class java2d.Tools
java.lang.UnsupportedOperationException: class redefinition failed: attempted to delete a method
        at sun.instrument.InstrumentationImpl.retransformClasses0(Native Method)
        at sun.instrument.InstrumentationImpl.retransformClasses(InstrumentationImpl.java:116)
        at TestAgent.reloadClasses(TestAgent.java:47)
        at TestAgent.run(TestAgent.java:31)
        at java.lang.Thread.run(Thread.java:611)

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
TestAgent.java
------------------------------------------------------------------------------
import java.lang.instrument.*;

public class TestAgent
	implements Runnable
{
	private final Instrumentation fInstrumentation;

	public static void
	premain(	String agentArgs,
				Instrumentation instrumentation)
	{
		System.out.println("TestAgent started");
		new Thread(new TestAgent(instrumentation)).start();
	}
	
	public
	TestAgent(	Instrumentation instrumentation)
	{
		fInstrumentation = instrumentation;
	}

	public void
	run()
	{
		// wait for some classes to be loaded
		try { Thread.sleep(5000); } catch (InterruptedException ie) {}
		reloadClasses();
	}

    public void
    reloadClasses()
    {
        Class[] allClasses = fInstrumentation.getAllLoadedClasses();
        for (int i = 0; i < allClasses.length; i++)
        {
            try
            {
                // ignore arrays, primitives and classes loaded from the bootstrap loader
                if (!allClasses[i].isArray() &&
                    !allClasses[i].isPrimitive() &&
                     allClasses[i].getClassLoader() != null)
                {
                	fInstrumentation.retransformClasses(new Class[] { allClasses[i] });
                }
            }
            catch (Exception e)
            {
            	System.out.println("Retransform failed for " + allClasses[i]);
                e.printStackTrace();
            }
        }
    }
}
------------------------------------------------------------------------------


TestAgent.mf
------------------------------------------------------------------------------
Manifest-Version: 1.0
Premain-Class: TestAgent
------------------------------------------------------------------------------

---------- END SOURCE ----------
Response from filer:
Adding the Can-Retransform-Classes manifest entry appears to make the
problem go away for static agents (loaded using the -javaagent option).
The error message is still very misleading though.  Something like
"retransform not enabled for this agent" would make more sense.

The problem still occurs when loading the Agent via the remote attach
feature, even with this new manifest attribute.  I've attached an
updated TestAgent.jar with the new manifest attribute that also supports
remote attach.
It works using -javaagent but has the same problem when loaded via
remote attach.
--

I ran the test on Windows with b52 and it duplicates with -javaagent (not just a late-binding agent).

Comments
SUGGESTED FIX The fix for this bug is incomplete. See the following bug: 6393258 2/1 crash: redefine classes method order change incomplete
02-03-2006

SUGGESTED FIX See attached 6328000-webrev-cr0.tgz for the proposed fix.
21-11-2005

SUGGESTED FIX compare_class_versions() needs to change into compare_and_normalize_class_versions() where out of order overloaded methods in scratch_class are sorted into an order that matches the_class.
21-11-2005

EVALUATION The assumption about method order remaining the same is true in other parts of the VM also. Consider a class hierarchy where C1 is subclassed by C2 which is subclassed by C3. If C2 is redefined and the order of overloaded methods are changed, then C3 (which has not been redefined) can get confused about where to find its super's version of a method.
21-11-2005

SUGGESTED FIX Matching method search should mimic instanceKlass::find_method which first checks the same index, then before, and after.
27-09-2005

EVALUATION jvmtiRedefineClasses.cpp assumes that methods, since they are sorted, are always in the same order. However, they are sorted only on method name and thus overloaded methods may not have a consistent order. This has been observed as a problem in class retransformation.
27-09-2005

EVALUATION The error stems from the an UNSUPPORTED_REDEFINITION_METHOD_DELETED from JVMTI's RedefineClasses so moving to hotspot/jvmti category.
23-09-2005