美文网首页
Javassit ClassPool.getDefault的问题

Javassit ClassPool.getDefault的问题

作者: 健忘仙森 | 来源:发表于2019-11-30 12:15 被阅读0次

在Android开发中,我们经常通过Gradle Plugin配合Android Gradle Plugin提供的Tranform API,并应用Javassit字节码编辑库在Android打包过程中做一些特殊操作。例如:自动埋点,热修复等。

Javassit提供了一个方便获取ClassPool的方法,ClassPool.getDefault()它是个单列对象

当你在使用assemble命令打包你的Android应用时,默认会执行assembleDebugassembleRelease,如果你增加了定义的buildTypes或者flavors,所有的assembleXXX命令都会执行。因此assemble多次调用void transform(TransformInvocation transformInvocation)方法。

此时,如果你是使用ClassPool.getDefault()来存放你需要操作的Class,并且在自定义Transform中对CtClass应用writeFile()toClass()或者toByteCode()方法将其转换成Class文件,那么Javassist就会冻结(frozen)这个CtClass对象,之后就不能修改这个CtClass对象了。所以transform方法第二次执行时,我们在对ClassPool.getDefault()里面的CtClasswriteFile()toClass()或者toByteCode()操作就会发生xxx class is frozen.的错误。

Javassit的此异常是为了警告开发者不要修改已经被JVM加载的class文件,因为JVM不允许重新加载一个类。

解决方法:不要使用ClassPool.getDefault()来获取ClassPool,通过ClassPool classPool = new ClassPool(true)的方式自己创建,因为每次都是新创建的ClassPool,所以在执行assemble后多次调用void transform(TransformInvocation transformInvocation)方法不会出现上述异常。

相关文章

  • Javassit ClassPool.getDefault的问题

    在Android开发中,我们经常通过Gradle Plugin配合Android Gradle Plugin提供的...

  • Javassit动态代理

    背景 最近在处理一个生产问题的时候,看到依赖的三方库中用到了javassit 作为动态代理,然后就着手学习了jav...

  • Javassit 发布groovy到本地

  • Cglib动态代理

    背景 上一篇文章写了javassit实现动态代理传送门,本篇文章用cglib来实现一下。 废话不多说,直接撸代码。...

  • 字节码插桩实战 javassit + gradle transf

    前言:上一篇[https://www.jianshu.com/p/a07a910ebfd0]我们简单介绍了下字节码...

  • 问题的问题

    “你别总给我说问题、问题,给我提一些建设性的建议行不?” “你咋变成了意见篓子?” 满腔热血地跑到领导面前表功,结...

  • 问题的问题

    “你别总给我说问题、问题,给我提些建设性的建议行不?” “你咋变成了意见篓子?” 满腔热血地跑到领导面前表功,结果...

  • 问题的问题

    问题家庭的问题是:家长本身用着有问题的方法教育孩子,没问题的孩子也变得有问题。 而且更严重的问题是:家长并没有意识...

  • 问题 的问题

    人大部分时间是在矛盾中挣扎着,有时候是心里想的是这样,但是不得不面对现实和道德,而选择了与内心不相符的决定...

  • 问题的问题

    现实问题,很多生活中,男人考虑问题往往没有女人周全,细致,男人只看生活的表面,然而女人,看的是生活的全面问题,就像...

网友评论

      本文标题:Javassit ClassPool.getDefault的问题

      本文链接:https://www.haomeiwen.com/subject/nghowctx.html