`
zhb8015
  • 浏览: 399487 次
  • 性别: Icon_minigender_1
  • 来自: 北京
博客专栏
Group-logo
Spring Roo杂谈
浏览量:0
社区版块
存档分类
最新评论

java字节码操作

阅读更多

你知道如何操作JAVA字节码文件吗,这里将介绍与操作Java字节码有关的基本知识和操作Java字节码的方法及Demo,首先我们来看一下AOP的概念,AOP是OOP的延续,是AspectOrientedProgramming的缩写,意思是面向方面编程。

  如何操作JAVA字节码文件

  本文将介绍与操作Java字节码有关的基本知识和操作Java字节码的方法及Demo,谈到操作Java字节码,不能不谈到AOP(AspectOrientedProgramming),下面来简单介绍一下:

  AOP简介

  AOP是OOP的延续,是AspectOrientedProgramming的缩写,意思是面向方面编程。AOP实际是GoF设计模式的延续,设计模式孜孜不倦追求的是调用者和被调用者之间的解耦,AOP可以说也是这种目标的一种实现。

   AOP的一个典型应用就是J2EE。J2EE应用系统只有部署在J2EE容器中才能运行,那么为什么划分为J2EE容器和J2EE应用系统?通过对 J2EE容器运行机制的分析,可以发现:实际上J2EE容器分离了一般应用系统的一些通用功能,例如事务机制、安全机制以及对象池或线程池等性能优化机 制。

  这些功能机制是每个应用系统几乎都需要的,因此可以从具体应用系统中分离出来,形成一个通用的框架平台,而且,这些功能机制的设计 开发有一定难度,同时运行的稳定性和快速性都非常重要,必须经过长时间调试和运行经验积累而成,因此,形成了专门的J2EE容器服务器产品,如 TomcatJBoss。

  简单了解AOP后,再来了解一下AOP底层技术:

  AOP(AspectOrientedProgramming)底层技术比较

  从上面的图表中分析可以看到,对于一般的操作Java字节码要求(实际上是能够满足笔者100%的要求),综合考虑功能,性能,可用性,易用性,使用Java字节码框架来操作Java字节码是最佳的选择。

  下面来了解一下都有哪些开源操作JavaJava字节码的框架:

  Javassist;

  cglib;

  SERP;

  Packagegnu.bytecode;

  Cojen;

  Jdec;

  BCEL;

  ObjectWebASM;

  JClassLib;

  TroveClassFileAPI;

  Jiapi;

  ClassfileReader&Writer;

  JBET;

  Retroweaver;

  Jen;

  Soot

 

 

这里重点介绍一下ASM,因为下面将使用ASM框架进行Java字节码修改。

  ASM这个Java字节码操控框架能被用来动态生成类或者增强既有类的功能。ASM可以直接产生二进制class文件,也可以在类被加载入 Java虚拟机之前动态改变类行为。Javaclass被存储在严格格式定义的.class文件里,这些类文件拥有足够的元数据来解析类中的所有元素:类 名称、方法、属性以及Java字节码(指令)。ASM从类文件中读入信息后,能够改变类行为,分析类信息,甚至能够根据用户要求生成新类。下图对当前接触 常用的操作Java字节码框架进行了一个比较:

 

 

  ASM的几个特性:

 

  1.JAVABased.

 

  ASM是基于JAVA的,即用JAVA实现的。

 

  2.Visitor模式.

 

  对于ASM来说,Javaclass被描述为一棵树;使用“Visitor”模式遍历整个二进制结构。

 

  3.复杂性低.易学易用.

 

  ASM提供了更为现代的编程模型,降低了操作Java字节码的复杂性,使用事件驱动的处理方式使得用户只需要关注于对其编程有意义的部分,而不必了解Java类文件格式的所有细节:ASM框架提供了默认的“responsetaker”处理这一切。

 

  4.较高的性能

 

  对Java字节码进行操作的同时尽量减小的性能的损失(性能的损失是不可避免)。

 

  这里来介绍一下ASM组成及顺序图:

 

 

  Corepackage提供了一个读写、修改Javabytecode的API,并且为其它的package定义了依据。这个package对于生成Javabytecode、实现大多数的bytecode变换而言意义重大。

 

  Treepackage提供了Javabytecode的内存表示法。

 

  Analysispackage提供了基本的数据流分析和类型检查算法,它们将用于在treeoackage中存储Java方法bytecode。

 

  Commonspackage(包含在ASM2.0中)提供了一些常用的bytecode转换和用于简化bytecode生成的适配器。

 

  Utilpackage包含了一些帮助类和简单的bytecode验证器,它们将有助于开发或者测试。

 

  XMLpackage提供了一个用于在bytecode和XML之间进行转换的适配器,和一些允许使用XSLT定义bytecode转换的兼容SAX的适配器。

 

  顺序图:

 

 

***************************************************************************************

 Demo

  这里我们来实现这样一个功能:在不能改变原代码功能的前提下,对于一个特定类的特定方法有没有被测试过,以HelloTaobao类中方法helloHeyun为例。

 

  类HelloTaobao:

 

 

  • publicclassHelloTaobao  
  • {  
  • publicvoidhelloHeyun()  
  • {  
  • System.out.println(“Hello,ThisisHeyun’sinvestigationaboutcodecoverage!”);  
  • }  
  • }

 

  主方法类:

 

 

  • publicclassMain  
  • {  
  • publicstaticvoidmain(String[]args)  
  • {  
  • HelloTaobaoht=newHelloTaobao();  
  • ht.heyunHeyun();  
  • }  
  • }  

 

  到这里,我们运行一下程序,会在Console输出字符串:“Hello,ThisisHeyun’sinvestigationaboutcodecoverage!”。

 

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

 

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

 

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

 

 

  • publicclassGenerator  
  • {  
  • publicstaticvoidmain(String[]args)throwsException  
  • {  
  • ClassReadercr=newClassReader(“HellTaobao”);  
  •  
  • ClassWritercw=newClassWriter(ClassWriter.COMPUTE_MAXS);  
  •  
  • ClassAdapterclassAdapter=newByteCodeClassHandler(cw);  
  •  
  • cr.accept(classAdapter,ClassReader.SKIP_DEBUG);  
  •  
  • byte[]data=cw.toByteArray();  
  •  
  • Filefile=newFile(“HellTaobao.class”);  
  •  
  • FileOutputStreamfout=newFileOutputStream(file);  
  •  
  • fout.write(data);  
  •  
  • fout.close();  
  • }  
  • }

 

 

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

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

 

  • publicclassByteCodeClassHandlerextendsClassAdapter  
  • {  
  • publicByteCodeClassHandler(ClassVisitorcv)  
  • {  
  • super(cv);  
  • }  
  • publicvoidvisit(intversion,intaccess,Stringname,Stringsignature,  
  • StringsuperName,String[]interfaces)  
  • {  
  • super.visit(version,access,name,signature,superName,interfaces);  
  • }  
  • publicvoidvisitSource(Stringsource,Stringdebug)  
  • {  
  • super.visitSource(source,debug);  
  •  
  • }  
  • publicvoidvisitEnd()  
  • {  
  • }  
  •  
  • @Override  
  •  
  • publicMethodVisitorvisitMethod(intaccess,Stringname,Stringdesc,  
  •  
  • Stringsignature,String[]exceptions)  
  • {  
  • MethodVisitormv=cv.visitMethod(access,name,desc,signature,  
  •  
  • exceptions);  
  •  
  • MethodVisitorwrappedMv=mv;  
  •  
  • if(mv!=null)  
  •  
  • {  
  •  
  • //对于”helloHeyun”方法进行改造  
  •  
  • if(name.equals(“helloHeyun”))  
  • {  
  •  
  • //使用自定义MethodVisitor,改写方法内容  
  •  
  • wrappedMv=newByteCodeMethodHandler(mv);  
  • }  
  • }  
  • returnwrappedMv;  
  • }  
  • }

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

 

  • publicclassByteCodeMethodHandlerextendsMethodAdapter  
  • {  
  • publicByteCodeMethodHandler(MethodVisitormv)  
  • {  
  • super(mv);  
  • }  
  • publicvoidvisitCode()  
  • {  
  • visitMethodInsn(Opcodes.INVOKESTATIC,“ControlByteCode”,  
  •  
  • “controlByteCodeByHeyun”,“()V”);  
  • }  
  • }  

 

 

 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(插装)的。

分享到:
评论

相关推荐

    JAVA字节码操作库 BCEL

    **JAVA字节码操作库 BCEL** BCEL(Byte Code Engineering Library)是Java开发的一个重要工具,主要用于处理Java字节码。它为开发者提供了一种深入理解与操作Java类文件的底层机制,允许分析、创建、修改和优化字节...

    java源码:JAVA字节码操作库 BCEL.zip

    Java字节码操作库BCEL(Byte Code Engineering Library)是一个强大的工具,用于分析、修改和创建Java类文件。它是Apache软件基金会的Jakarta项目的一部分,为开发者提供了对字节码的底层控制,使得开发者能够在运行...

    JAVA字节码操作库 BCEL.7z

    **JAVA字节码操作库 BCEL** BCEL(Byte Code Engineering Library)是Java平台上的一款开源库,主要用于处理Java字节码。它提供了对字节码的解析、创建、修改和分析的能力,使得开发者能够深入理解并操作Java类文件...

    ASM Java字节码操作框架

    ASM Java字节码操作框架PPT,结合已有AOP实现方法,对比所有对Java字节码操作方法做比较

    JAVA源码JAVA字节码操作库BCEL

    JAVA源码JAVA字节码操作库BCEL

    java资源JAVA字节码操作库BCEL

    java资源JAVA字节码操作库 BCEL提取方式是百度网盘分享地址

    Java 字节码概述

    Java 字节码操作码可以分为以下几类: * 保留操作码(3) * 装载和存储(71) * 运算指令(42) * 类型转换指令(15) * 操作数栈管理指令(9) * 控制转移指令(23) * 对象创建和操纵指令(27) * 方法调用和返回...

    ASM 帮助文档(java字节码操作)

    ASM 帮助文档(java字节码操作) 对字节码进行操作的jar包。

    Recaf一个现代Java字节码编辑器

    **Recaf:现代Java字节码编辑器** 在Java开发领域,字节码编辑器是一种不可或缺的工具,...在实际使用中,配合其提供的文档和社区资源,开发者可以更深入地掌握Java字节码操作的技巧,提升开发效率和解决问题的能力。

    Java字节码工程工具包.zip

    Java字节码工程工具包Javassist 版本 3版权所有 (C) 1999-2023 Shigeru Chiba,保留所有权利。Javassist(JAVA 编程助手)使 Java 字节码操作变得简单。它是一个用于编辑 Java 字节码的类库它使 Java 程序能够在运行...

    轻松看懂Java字节码.pdf

    标题《轻松看懂Java字节码.pdf》中隐藏的知识点是理解Java字节码的重要性及如何轻松掌握。描述中提到Java字节码是实现“一次编写,到处运行”(Write Once, Run Anywhere)这一Java承诺的核心技术之一。而标签“Java...

    免费开源!!Java字节码工程工具包

    Javassist(JAVA 编程助手)使 Java 字节码操作变得简单。它是Java中用于编辑字节码的类库;它使 Java 程序能够在运行时定义新类,并在 JVM 加载时修改类文件。与其他类似的字节码编辑器不同,Javassist 提供两个...

    java字节码加密

    Java字节码加密是保护Java应用程序源代码安全的重要技术手段,主要是为了防止恶意用户逆向工程分析、篡改或盗取程序的核心逻辑。在Java中,字节码(Bytecode)是程序经过编译后的中间表示,可以直接由Java虚拟机...

    javassist, Java字节码工程工具包.zip

    javassist, Java字节码工程工具包 Java字节码工程工具包 版本 3版权所有( C ) 1999 -2017按 Shigeru Chiba,保留所有权利。Javassist ( Java编程助手) 使Java字节码操作简单。 它是一个类库,用于在Java中编辑字节码

    ASM字节码操作简单实例

    ASM字节码库是Java字节码操作的强大工具,它允许程序员在运行时动态生成类或者增强已有类的功能。在本实例中,我们将探讨如何利用ASM实现简单的面向切面编程(AOP)功能,这是一种在不修改源代码的情况下,添加额外...

    基于java的字节码操作库 BCEL.zip

    Java字节码操作库BCEL(Byte Code Engineering Library)是一个强大的工具,主要用于处理Java字节码,它允许开发者分析、创建、修改以及动态生成类。BCEL是Apache软件基金会下的Jakarta项目的一部分,广泛应用于软件...

    基于Java的字节码操作库 BCEL.zip

    Java字节码操作库BCEL(Byte Code Engineering Library)是一个强大的工具,主要用于处理Java类文件。它提供了对字节码的全面访问和控制,允许开发者分析、修改和创建新的Java类。BCEL在许多领域都有应用,如动态...

    Java字节码转换工具—Retrotranslator

    Java字节码转换工具Retrotranslator是一个用于解决软件兼容性问题的实用工具,尤其是在Java版本升级带来的不兼容性上。随着Java技术的不断迭代,新版本的特性常常不能在旧版本的JDK环境下运行,而Retrotranslator的...

    cglib,字节码生成库是生成和转换Java字节码的高级API。它被aop、测试、数据访问框架用来生成动态代理对象和拦截字段访问。.zip

    CGlib库利用ASM库(一个底层的Java字节码操作和分析框架)来生成和修改字节码。通过这种方式,开发者可以在程序运行时动态地创建新的类或修改现有类的行为,而无需重新编译源代码。 **动态代理** CGlib常用于实现...

Global site tag (gtag.js) - Google Analytics