I am new to instrumentation. I need to add a static variable and maybe a static method later on in one of bootstrap classes, java.lang.String. I tried both Javassist and ASM but both report error,
> Exception in thread "main" java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at sun.instrument.InstrumentationImpl.loadClassAndStartAgent(Unknown Sou
rce)
at sun.instrument.InstrumentationImpl.loadClassAndCallPremain(Unknown So
urce)
Caused by: java.lang.UnsupportedOperationException: class redefinition failed: a
ttempted to change the schema (add/remove fields)
at sun.instrument.InstrumentationImpl.retransformClasses0(Native Method)
at sun.instrument.InstrumentationImpl.retransformClasses(Unknown Source)
here is my transform method and ASM code,
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
ProtectionDomain domain, byte[] classfileBuffer)
{
if (className.startsWith("java/lang/String")) {
try {
classfileBuffer = modifyField(classfileBuffer);
} catch (Exception e) {
e.printStackTrace();
}
return classfileBuffer
}
public static byte[] modifyField(byte[] origClassData) throws Exception {
ClassReader cr = new ClassReader(origClassData);
final ClassWriter cw = new ClassWriter(cr, ASM5);
// add the static final fields
cw.visitField(ACC_PUBLIC + ACC_FINAL + ACC_STATIC, "bVal","Z", null, new Boolean("false")).visitEnd();
// wrap the ClassWriter with a ClassVisitor that adds the static block to
// initialize the above fields
ClassVisitor cv = new CustomVisitor(ASM5, cw);
// feed the original class to the wrapped ClassVisitor
cr.accept(cv, 0);
// produce the modified class
byte[] newClassData = cw.toByteArray();
return newClassData;
}
I have also turned TRUE on both Can-Redefine-Classes and Can-Retransform-Classes.
Thanks for your help