ASM Handling of method Synthetic attribute causes exception during retransformation
I have written a Java Agent (using the java.lang.instrument interface) that
uses ASM to transform classes. My Agent supports retransformation to allow
classes to be restored to their original bytes at runtime.
This process fails when I work with a class which includes a method with the
"Synthetic" attribute. When I attempt to retransform the class back to its
source bytes I get the following exception.
java.lang.UnsupportedOperationException: class redefinition failed: attempted
to change method modifiers
at sun.instrument.InstrumentationImpl.retransformClasses0(Native Method)
at
sun.instrument.InstrumentationImpl.retransformClasses(InstrumentationImpl.java:124)
...
Section 4.8.7 of
http://java.sun.com/docs/books/jvms/second_edition/ClassFileFormat-Java5.pdf
states that a method can be marked as "Synthetic" using either an access bit or
an Attribute.
I have determined that the exception above is caused by ASM transforming the
source method (which has the Synthetic attribute) into a method without the
Synthetic attribute but with the synthetic access bit set. These are
semantically the same but the JVM evidently does not support switching between
these approaches at runtime.
This bug can be fixed by commenting out lines 740-741 of
org\objectweb\asm\ClassReader.java:
else if ("Synthetic".equals(attrName)) {
access |= Opcodes.ACC_SYNTHETIC;
}
With these lines commented out the synthetic attribute is not translated into a
synthetic bit.
There are similar blocks of code on the following lines.
535-536: Class level synethetic handling
645-646: Field level synethetic handling
These have not directly caused me problems but I suspect they will suffer from
the same problem.