我需要热交换各种类的方法实现(直到运行时的某个时候我才知道它的新实现,并且可能会再次改变)。
ByteBuddy
可以很容易地做到这一点,但它(显然)除了拦截它之外对方法做不了太多,这就是它与 ASM 一起提供的原因。
基本用法是
ByteBuddyAgent.install();
byte[] bytes = transformFoo();
ClassFileLocator classFileLocator = ClassFileLocator.Simple.of(Foo.class.getName(), bytes);
new ByteBuddy()
.redefine(Foo.class, classFileLocator)
.make()
.load(Foo.class.getClassLoader(), ClassReloadingStrategy.fromInstalledAgent());
在哪里
private static byte[] transformFoo() throws IOException {
ClassReader classReader = new ClassReader(Foo.class.getResourceAsStream("Foo.class"));
ClassWriter classWriter = new ClassWriter(classReader, 0);
MyClassVisitor myClassVisitor = new MyClassVisitor(classWriter);
classReader.accept(myClassVisitor, 0);
return classWriter.toByteArray();
}
正在使用 ASM。
但是 ASM 很乏味,很难阅读和编写更复杂的代码。所以我更愿意使用 Jimple,因为它为 if-stmts 等提供了抽象。
因此,这个想法是从
Class<?> fooClass = Foo.class;
,以某种方式将其转换为
SootClass fooSootClass = ...
,在那里转换方法,并以某种方式将其编译回byte[]
byte[] ret = ...
return ret;
stByteBuddy
可以重新加载类。
简而言之:
我想SootClass
从 a创建一个可转换的Class<?>
并将其编译为byte[]
我可以传递的 a。
我怎么做?
更新
这似乎暗示执行从SootClass
to的转换很热byte[]
,但到目前为止,我还没有找到任何有助于从Class
to转换的文档或示例SootClass
。大多数示例似乎只在加载类之前对其进行一次检测。