Byte Buddy installOn API giving error: adding retransformable transformers is not supported?
Byte Buddy installOn API giving error: adding retransformable transformers is not supported?
为什么 installOn API 在我的代码中出现错误。我想从另一个线程调用 instrumentation.retransformClasses API。
或者我们可以在 bytebuddy 中调用 instrumentation.retransformClasses API。
我想在 class 加载后插入一个静态字段。如果可能的话,一个简短的例子会很棒!
public static void premain(String arguments, Instrumentation instrumentation) {
System.out.println("Agent for add fields ");
final ByteBuddy byteBuddy = new ByteBuddy().with(Implementation.Context.Disabled.Factory.INSTANCE);
new AgentBuilder.Default()
.with(byteBuddy).with(RedefinitionStrategy.RETRANSFORMATION)
.with(new AgentBuilder.InitializationStrategy.SelfInjection.Eager())
.with(TypeStrategy.Default.REDEFINE)
.type((ElementMatchers.nameContains("Method")))
.transform(new Transformer() {
public Builder<?> transform(Builder<?> arg0, TypeDescription arg1, ClassLoader arg2,
JavaModule arg3) {
// TODO Auto-generated method stub
return null;
}
})
.installOn(instrumentation);
Thread thread = new Thread() {
public void run() {
System.out.println("Thread Running");
try {
Thread.currentThread().sleep(10000);
Class c[] = instrumentation.getAllLoadedClasses();
for (int i = 0; i < c.length; i++) {
String clsName = c[i].getName();
System.out.println(clsName);
if (clsName.equals("com.github.shehanperera.example.Method")) {
instrumentation.retransformClasses(c[i]);
}
}
} catch (Exception e) {
e.printStackTrace();
System.out.println(e);
}
}
};
thread.start();
}
给出异常:
Exception in thread "main" java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.instrument.InstrumentationImpl.loadClassAndStartAgent(InstrumentationImpl.java:386)
at sun.instrument.InstrumentationImpl.loadClassAndCallPremain(InstrumentationImpl.java:401)
Caused by: java.lang.IllegalStateException: Could not install class file transformer
at net.bytebuddy.agent.builder.AgentBuilder$Default.installOn(AgentBuilder.java:8538)
at net.bytebuddy.agent.builder.AgentBuilder$Default$Delegator.installOn(AgentBuilder.java:10179)
at com.github.shehanperera.addfield.Agent.premain(Agent.java:39)
... 6 more
Caused by: java.lang.UnsupportedOperationException: adding retransformable transformers is not supported in this environment
at sun.instrument.InstrumentationImpl.addTransformer(InstrumentationImpl.java:88)
at net.bytebuddy.agent.builder.AgentBuilder$Default.installOn(AgentBuilder.java:8514)
... 8 more
FATAL ERROR in native method: processing of -javaagent failed
Javassist 默认情况下不允许任何类似的事情,javassist 只是做了一些简单的巧妙技巧并允许您在实际加载之前编辑 class,因为 classes 在第一次使用时加载。否则也必须使用具有重新转换的典型代理。
并且要创建可以重新转换 classes 的工具,您必须向清单添加适当的标志:
可以重新转换-类: true
https://docs.oracle.com/javase/7/docs/api/java/lang/instrument/Instrumentation.html
为什么 installOn API 在我的代码中出现错误。我想从另一个线程调用 instrumentation.retransformClasses API。 或者我们可以在 bytebuddy 中调用 instrumentation.retransformClasses API。 我想在 class 加载后插入一个静态字段。如果可能的话,一个简短的例子会很棒!
public static void premain(String arguments, Instrumentation instrumentation) {
System.out.println("Agent for add fields ");
final ByteBuddy byteBuddy = new ByteBuddy().with(Implementation.Context.Disabled.Factory.INSTANCE);
new AgentBuilder.Default()
.with(byteBuddy).with(RedefinitionStrategy.RETRANSFORMATION)
.with(new AgentBuilder.InitializationStrategy.SelfInjection.Eager())
.with(TypeStrategy.Default.REDEFINE)
.type((ElementMatchers.nameContains("Method")))
.transform(new Transformer() {
public Builder<?> transform(Builder<?> arg0, TypeDescription arg1, ClassLoader arg2,
JavaModule arg3) {
// TODO Auto-generated method stub
return null;
}
})
.installOn(instrumentation);
Thread thread = new Thread() {
public void run() {
System.out.println("Thread Running");
try {
Thread.currentThread().sleep(10000);
Class c[] = instrumentation.getAllLoadedClasses();
for (int i = 0; i < c.length; i++) {
String clsName = c[i].getName();
System.out.println(clsName);
if (clsName.equals("com.github.shehanperera.example.Method")) {
instrumentation.retransformClasses(c[i]);
}
}
} catch (Exception e) {
e.printStackTrace();
System.out.println(e);
}
}
};
thread.start();
}
给出异常:
Exception in thread "main" java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.instrument.InstrumentationImpl.loadClassAndStartAgent(InstrumentationImpl.java:386)
at sun.instrument.InstrumentationImpl.loadClassAndCallPremain(InstrumentationImpl.java:401)
Caused by: java.lang.IllegalStateException: Could not install class file transformer
at net.bytebuddy.agent.builder.AgentBuilder$Default.installOn(AgentBuilder.java:8538)
at net.bytebuddy.agent.builder.AgentBuilder$Default$Delegator.installOn(AgentBuilder.java:10179)
at com.github.shehanperera.addfield.Agent.premain(Agent.java:39)
... 6 more
Caused by: java.lang.UnsupportedOperationException: adding retransformable transformers is not supported in this environment
at sun.instrument.InstrumentationImpl.addTransformer(InstrumentationImpl.java:88)
at net.bytebuddy.agent.builder.AgentBuilder$Default.installOn(AgentBuilder.java:8514)
... 8 more
FATAL ERROR in native method: processing of -javaagent failed
Javassist 默认情况下不允许任何类似的事情,javassist 只是做了一些简单的巧妙技巧并允许您在实际加载之前编辑 class,因为 classes 在第一次使用时加载。否则也必须使用具有重新转换的典型代理。
并且要创建可以重新转换 classes 的工具,您必须向清单添加适当的标志:
可以重新转换-类: true
https://docs.oracle.com/javase/7/docs/api/java/lang/instrument/Instrumentation.html