JAVA字节码文件操作技巧(3)

  • 本文将介绍与操作Java字节码有关的基本知识和操作Java字节码的方法及Demo,谈到操作Java字节码,不能不谈到AOP,这里向大家做一下简单介绍。
  •  
    1. IBM发布Java字节码配置工具包BIPTK
    2. 深入学习JVM内存设置原理和调优
    3. JVM.dll装载过程与源代码分析
    4. 巧解使Eclipse崩溃的JVM terminated问题
    5. 解决JVM Terminated.ExitCode=-1问题行之有效的方法
  •  

    下面我们来操作一下Java字节码文件HelloTaobao.class:

    1.想操作Java字节码的某一方法,需要继承ASM中的ClassAdapter和MethodAdapter

    2.定义类Generator来读入Java字节码文件HellTaobao,改造Java字节码文件,生成改造后的同名Java字节码文件HellTaobao,代码如下:

       
       
    1. publicclassGenerator  
    2. {  
    3. publicstaticvoidmain(String[]args)throwsException  
    4. {  
    5. ClassReadercr=newClassReader(“HellTaobao”);  
    6.  
    7. ClassWritercw=newClassWriter(ClassWriter.COMPUTE_MAXS);  
    8.  
    9. ClassAdapterclassAdapter=newByteCodeClassHandler(cw);  
    10.  
    11. cr.accept(classAdapter,ClassReader.SKIP_DEBUG);  
    12.  
    13. byte[]data=cw.toByteArray();  
    14.  
    15. Filefile=newFile(“HellTaobao.class”);  
    16.  
    17. FileOutputStreamfout=newFileOutputStream(file);  
    18.  
    19. fout.write(data);  
    20.  
    21. fout.close();  
    22. }  
    23. }  
    24.  

    3.ByteCodeClassHandler(自定义)类继承ClassAdapter(fromASM)

    4.ByteCodeClassHandler类中重写visitMethod,这个方法里去判断如果Java字节码文件HelloTaobao.class包含方法helloHeyun就调用ByteCodeMethodHandler类

       
       
    1. publicclassByteCodeClassHandlerextendsClassAdapter  
    2. {  
    3. publicByteCodeClassHandler(ClassVisitorcv)  
    4. {  
    5. super(cv);  
    6. }  
    7. publicvoidvisit(intversion,intaccess,Stringname,Stringsignature,  
    8. StringsuperName,String[]interfaces)  
    9. {  
    10. super.visit(version,access,name,signature,superName,interfaces);  
    11. }  
    12. publicvoidvisitSource(Stringsource,Stringdebug)  
    13. {  
    14. super.visitSource(source,debug);  
    15.  
    16. }  
    17. publicvoidvisitEnd()  
    18. {  
    19. }  
    20.  
    21. @Override  
    22.  
    23. publicMethodVisitorvisitMethod(intaccess,Stringname,Stringdesc,  
    24.  
    25. Stringsignature,String[]exceptions)  
    26. {  
    27. MethodVisitormv=cv.visitMethod(access,name,desc,signature,  
    28.  
    29. exceptions);  
    30.  
    31. MethodVisitorwrappedMv=mv;  
    32.  
    33. if(mv!=null)  
    34.  
    35. {  
    36.  
    37. //对于”helloHeyun”方法进行改造  
    38.  
    39. if(name.equals(“helloHeyun”))  
    40. {  
    41.  
    42. //使用自定义MethodVisitor,改写方法内容  
    43.  
    44. wrappedMv=newByteCodeMethodHandler(mv);  
    45. }  
    46. }  
    47. returnwrappedMv;  
    48. }  
    49. }  
    50.  

    5.ByteCodeMethodHandler(自定义)继承MethodAdapter(fromASM),这里来做改造想要调用的自定义方法,这里将调用类ControlByteCode(自定义)中的controlByteCodeByHeyun(自定义)方法

       
       
    1. publicclassByteCodeMethodHandlerextendsMethodAdapter  
    2. {  
    3. publicByteCodeMethodHandler(MethodVisitormv)  
    4. {  
    5. super(mv);  
    6. }  
    7. publicvoidvisitCode()  
    8. {  
    9. visitMethodInsn(Opcodes.INVOKESTATIC,“ControlByteCode”,  
    10.  
    11. “controlByteCodeByHeyun”,“()V”);  
    12. }  
    13. }  
    14.  

    6.ControlByteCode类的controlByteCodeByHeyun方法如下

       
       
    1. publicclassControlByteCode  
    2. {  
    3. publicstaticvoidcontrolByteCodeByHeyun()  
    4. {  
    5. System.out.println(“Thismethodhasalreadybeencovered.”);  
    6.  
    7. //TODOrealsecuritycheck  
    8. }  
    9. }  

    7.这样,当运行完Generator类中main方法后,会生成一个和原Java字节码文件同名的文件(可以观察出,会比以前的文件大,当然也可以用MD5来确定是两个不同文件)。

    8.此时在运行主方法类Main,会发现在Console打印如下:

       
       
    1. Hello,ThisisHeyun’sinvestigationaboutcodecoverage!  
    2.  
    3. Thismethodhasalreadybeencovered.  

    9.由此,可以看出,在原功能没有变化的前提下,通过改变Java字节码文件,我们实现了CodeCoverage的雏形。实际上,很多CodeCoverage工具(如Cobertura)都是运用此方法来实现Instrument(插装)的。

    【编辑推荐】

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值