JDK8将lambda表达式转换为
中的匿名类InnerClassLambdaMetafactory.spinInnerClass() {
return UNSAFE.defineAnonymousClass(targetClass, classBytes, null);
}
我正在编写javaagent,使用asm修改classBytes
(添加方法)并将其传递给defineAnonymousClass
,但该方法最终会出现此匿名类的ClassNotFoundException。有什么方法可以修改匿名classBytes的内容吗?
答案 0 :(得分:0)
转换匿名加载的类很棘手。您是否重新构建已经加载的代表此类的类?如果是这样,请注意Class::getName
不会返回类的实际二进制名称,但会添加一个随机哈希,例如my.DefinedType/12345
,您需要删除最新的数字。
此外,您不能直接从另一个类引用这些类,但您需要直接从反射API或理想情况下的方法句柄引用它们。你不能从类加载器中查找这些类,这就是它们被称为匿名的原因。
最后,在安装类文件转换器时,不会向变换器注册此类匿名类的加载。处理这些类的最简单方法是修补负责创建lambda类型的lambda元工厂。您可以使用例如允许您创建代理的Byte Buddy轻松完成此操作:
new AgentBuilder.Default()
.with(LambdaTransformationStrategy.ENABLED)
.type(someMatcher)
.transform(someTransformer)
.installOn(instrumentation);
调用此内容,Byte Buddy重写了JVM的默认lambda元工厂类,并将其替换为可以进行此类检测的自己的代码生成。