bytebuddy对于final类的增强
尝试对Spring里的一个 类进行增强,使用了bytebuddy进行增强。但是一直不成功。 最后发现这个类是final类,把排查过程记录如下:
第一步:尝试用bytebuddy对Spring的类进行增强,一直不成功,并且基于Spring的应用启动报错。
第二步:打开bytebuddy的调试功能,并注册到Agent上:
// 声明Listener AgentBuilder.Listener listener = new AgentBuilder.Listener() { @Override public void onDiscovery(String typeName, ClassLoader classLoader, JavaModule module, boolean loaded) { } @Override public void onTransformation(TypeDescription typeDescription, ClassLoader classLoader, JavaModule module, boolean loaded, DynamicType dynamicType) { logger.info("transformation:" + typeDescription.getSimpleName()); try { dynamicType.toJar(new File("./dumpbuddy.jar")); } catch (IOException e) { e.printStackTrace(); } } @Override public void onIgnored(TypeDescription typeDescription, ClassLoader classLoader, JavaModule module, boolean loaded) { } @Override public void onError(String typeName, ClassLoader classLoader, JavaModule module, boolean loaded, Throwable throwable) { logger.error("handle type:" + typeName + " error"); } @Override public void onComplete(String typeName, ClassLoader classLoader, JavaModule module, boolean loaded) { } }; //注册listener new AgentBuilder.Default() .type(named("org.springframework.context.support.AbstractApplicationContext")) .transform(new AgentBuilder.Transformer() { @Override public DynamicType.Builder<?> transform( DynamicType.Builder<?> builder, TypeDescription typeDescription, ClassLoader classLoader, JavaModule module) { //xxxxxxx } }).with(listener).installOn(instrumentation);
此时再启动被增强应用,在被增强应用的目录下,会产生一个 dumpbuddy.jar的文件,里面是刚刚被增强的类的基本信息。使用jd-gui.exe 这种工具可以反编译查看。
此时查看,发现增强部分的函数,只剩下一行了。 而且看起来明显功能不全。 经过查阅google, 说是bytebuddy 会遵循java的规范,对于final类,无法进行subclass的处理,此部分如果确实需要处理,需要使用javaassist等方式,人工处理字节码,去掉final的修饰符。