我需要对各种类的热交换方法实现(在运行期间我可能不知道的新实现,并且可能会再次更改)。
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;
s.t。 ByteBuddy
可以重新加载课程。
简而言之:
我想从SootClass
创建一个可转换的Class<?>
并将其编译为我可以传递的byte[]
。
我该怎么做?
更新
This似乎建议执行从SootClass
到byte[]
的转换,但到目前为止,我还没有能够找到任何类型的文档或示例有助于从Class
转换为SootClass
。大多数示例似乎只在一次加载之前对类进行检测。
答案 0 :(得分:0)