我正在用bytebuddyapi编写一个Java代理。因此,我想了解使用Bytebuddy DSL的重传功能加载的类的方法委派。当我使用参数javaagent启动应用程序时,一切正常,控制台输出也会更改,但当在运行时附加java代理时,会执行agentmain方法,但控制台输出不会更改。也许我错过了一些进一步的ByteBuddy配置。任何帮助都将不胜感激!
这是代理代码:
public class AgentMain {
private static final String CLASS = "testing.Test";
private static final String METHOD = "doSomething";
public static void premain(String agentArgs, Instrumentation instrumentation) {
System.out.println("premain...");
new AgentBuilder.Default()
.with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION)
.type(ElementMatchers.named(INSTRUMENTED_CLASS))
.transform(new AgentBuilder.Transformer() {
@Override
public DynamicType.Builder transform(
DynamicType.Builder builder,
TypeDescription typeDescription,
ClassLoader classLoader,
JavaModule javaModule
)
{
return builder.method(named(INTERCEPTED_METHOD))
.intercept(MethodDelegation.to(Interceptor.class));
}
}).installOn(instrumentation);
}
public static void agentmain(String agentArgs, Instrumentation instrumentation) {
System.out.println("Running agentmain...");
new AgentBuilder.Default()
.with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION)
.type(ElementMatchers.named(INSTRUMENTED_CLASS))
.transform(new AgentBuilder.Transformer() {
@Override
public DynamicType.Builder transform(
DynamicType.Builder builder,
TypeDescription typeDescription,
ClassLoader classLoader,
JavaModule javaModule
)
{
return builder.method(named(INTERCEPTED_METHOD))
.intercept(MethodDelegation.to(Interceptor.class));
}
}).installOn(instrumentation);
}
}
public class Interceptor {
public static void doSomething(String string) throws Exception {
System.out.println("Intercepted! ");
}
}
以下是应用程序代码:
public class Main {
public static void main(String args[]) throws Exception {
while (true) {
Thread.sleep(1000);
String say = "Not intercepted!";
Test test = new Test();
test.doSomething(say);
}
}
}
这是附加代理的代码:
public class Attacher {
public static void attach(String jarFile, String pid) {
try {
ByteBuddyAgent.attach(new File(jarFile), pid);
}
catch (Exception e) {
e.printStackTrace();
}
}
}
您可能需要添加. disableClassFormatChange()
,因为大多数JVM不支持在重新转换时更改类的形状。
另外,考虑注册一个代理生成器。侦听器查看类无法转换的原因。否则,instrumentation API将抑制所有错误。
通常,在重新传输时,通知API更适合于转换。它支持委托API的大多数功能,但工作原理略有不同。
字节伙伴代理是否能够克服附加API限制,例如“新方法定义”、“静态变量更改”?我可以看到,正在从代理生成器调用重定义类方法,但不确定这是否也遵循与附加API相同的限制。 我试图了解我是否可以做到以下几点: 1) 使用应用程序类加载器加载代理jar,例如并行WebAppClassLoader。我的应用程序是一个servlet webapp,在运行时它使用上面的类加载器加载所有应用程序类。 2) 完全
我试图在java上重新定义类。lang包,如String。类或整数。使用ByteBuddy初始化,但没有成功。我的问题是这是否可能? 这是我在我的java代理中尝试的代码: 当我检查日志的输出时,我看到的关于String类的内容是: 这是否意味着ByteBuddy没有重新定义String类?这可能吗? 非常感谢。
无法使用ByteBuddy重新定义java.io.ObjectInputStream。 我已经尝试了很多方法来解决这个问题。但我找不到钩住“java.io.ObjectInputStream$resolveClass”的方法。你能帮助我吗?
homebody能帮我提示一下如何使用byte buddy 1.6.9重新定义静态方法吗? 我试过这个: 我遇到以下异常: 线程“main”java.lang.IllegalStateException中的异常:无法注入已经加载的类型:类委托。来源 谢谢
例如,假设有一个接口(StoredOnDatabase)带有一些有用的方法,可以从数据库中读取和写入bean。假设有一些类没有实现这个接口,而是用注释@bean进行了注释。当这个注释出现时,我想: 创建实现StoredonDatabase接口的bean代理; 为setter添加拦截器,当bean的属性被修改时,我可以使用这些拦截器来“跟踪”; 使用对所有这些bean都有效的泛型equals()和h
我正在尝试在项目中检测一些类。当我将代理类打包到jar中并通过-javaagent使用它时,它工作正常。 当我尝试直接在项目中运行它时,检测有时会失败。(我在测试类的静态块中初始化bytepal)。 例如,当我添加这个测试时,我的代码不再被截获。用try/catch做同样的事情是有效的。 有没有一种安全的方法来仪器类在同一个项目没有-javaagent? 项目在OpenJdk11上。