我需要进行各种类别的热量塑料方法实现(直到在运行时,我才知道的新实现,并且可能会再次更改)。
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和theeles提供了抽象。
因此,这个想法是从
开始Class<?> fooClass = Foo.class;
,以某种方式将其转换为
SootClass fooSootClass = ...
,在那里转换方法,并以某种方式将其编译回byte[]
byte[] ret = ...
return ret;
s.t。ByteBuddy
可以重新加载类。
简而言之:
我想从Class<?>
创建可转换的SootClass
并将其编译为byte[]
,我可以传递。
我该怎么做?
更新
这似乎建议热以执行从SootClass
到byte[]
的转换,但是到目前为止,我还没有找到任何类型的文档或示例,这些文档或示例将有助于从Class
转换为SootClass
。大多数示例似乎只能加载一次课程一次。
我几年前尝试过,失败了。我会说从理论上讲可能是可能的,但这绝不容易。
一个问题是,当您尝试开发类型的课程时,通常您想使用java.lang.instrument在加载时间进行此操作。这意味着您只会一次看到一个课程,因为您本质上是在插入类加载过程。但是,对于烟灰的许多事情,它需要访问其他类。例如,它需要解决签名,有时甚至是方法主体。然后,这完全更改了一组加载类和加载的顺序。我记得这引起了很多问题。ASM没有这样的分辨率。