首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 其他教程 > 开源软件 >

ASM学习,摘引自http://qa.taobao.com/?p=6266

2012-06-30 
ASM学习,引用自http://qa.taobao.com/?p6266script typetext/javascript/script?script typete

ASM学习,引用自http://qa.taobao.com/?p=6266

<script type="text/javascript"></script>?ASM学习,摘引自http://qa.taobao.com/?p=6266<script type="text/javascript"></script>ASM学习,摘引自http://qa.taobao.com/?p=6266

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

l? Tree package提供了Java bytecode的内存表示法。

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

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

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

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

顺序图:

?ASM学习,摘引自http://qa.taobao.com/?p=6266

Demo

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

类HelloTaobao:

public class HelloTaobao

{

??? public void helloHeyun()

??? {??

??? System.out.println(“Hello, This is Heyun’s investigation about code coverage!”);??

??? }

}

主方法类:

public class Main

{

??? public static void main(String[] args)

??? {

?????? HelloTaobao ht = new HelloTaobao();

?????? ht.heyunHeyun();

??? }

}

到这里,我们运行一下程序,会在Console输出字符串:“Hello, This is Heyun’s investigation about code coverage!”

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

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

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

public class Generator

{

??? public static void main(String[] args) throws Exception

??? {

?????? ClassReader cr = new ClassReader(“HellTaobao”);

?????? ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);

?????? ClassAdapter classAdapter = new ByteCodeClassHandler(cw);

?????? cr.accept(classAdapter, ClassReader.SKIP_DEBUG);

?????? byte[] data = cw.toByteArray();

?????? File file = new File(“HellTaobao.class”);

?????? FileOutputStream fout = new FileOutputStream(file);

?????? fout.write(data);

?????? fout.close();

??? }

}

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

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

public class ByteCodeClassHandler extends ClassAdapter

{

??? public ByteCodeClassHandler(ClassVisitor cv)

??? {

?????? super(cv);

??? }

??? public void visit(int version, int access, String name, String signature,

?????????? String superName, String[] interfaces)

??? {

?????? super.visit(version, access, name, signature, superName, interfaces);

??? }

??? public void visitSource(String source, String debug)

??? {

?????? super.visitSource(source, debug);

??? }

??? public void visitEnd()

??? {?????

??? }

??? @Override?

??? public MethodVisitor visitMethod(int access, String name, String desc,

?????????? String signature, String[] exceptions)

??? {

?????? MethodVisitor mv = cv.visitMethod(access, name, desc, signature,

????????????? exceptions);

?????? MethodVisitor wrappedMv = mv;

?????? if (mv != null)

?????? {

?????????? // 对于 ” helloHeyun” 方法进行改造

?????????? if (name.equals(“helloHeyun”))

?????????? {

????????????? // 使用自定义 MethodVisitor,改写方法内容

????????????? wrappedMv = new ByteCodeMethodHandler(mv);

?????????? }

?????? }

?????? return wrappedMv;

??? }

}

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

public class ByteCodeMethodHandler extends MethodAdapter

{

??? public ByteCodeMethodHandler(MethodVisitor mv)

??? {

?????? super(mv);

??? }

??? public void visitCode()

??? {

?????? visitMethodInsn(Opcodes.INVOKESTATIC, “ControlByteCode”,

?????????? “controlByteCodeByHeyun”, “()V”);

??? }

}

6. ControlByteCode 类的controlByteCodeByHeyun 方法如下

public class ControlByteCode

{

??? public static void controlByteCodeByHeyun()

??? {??

??? System.out.println(“This method has already been covered.”);??

??????? //TODO real security check??

??? }

}

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

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

Hello, This is Heyun’s investigation about code coverage!

This method has already been covered.

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

应用

在介绍了AOP,ASM及如何利用ASM操作字节码Demo后,现在来看下一些使用ASM的典型应用:

l? BEA WebLogic Server 9

l? Berkeley DB Java Edition

l? Oracle TopLink

l? EclipseME

l? JRuby

l? Groovy

l? WebSphere sMash

更多可见http://asm.ow2.org/users.html

测试的联想

作为测试人员,有必要掌握这门技术,下面列出了笔者能想到的操作字节码这项技术对于测试的应用:

l? Code Coverage

l? Fault Injection

l? Profiler

参考:

http://asm.ow2.org/doc/tutorial-asm-2.0.html

http://java-source.net/open-source/bytecode-libraries

VN:F [1.9.7_1111]<!-- comments-header --> <!-- Feedsky FEED 订阅统计发布代码结束 -->
-- 订阅我吧! --订阅到 抓虾订阅到 鲜果订阅到 Google订阅到 有道订阅到 netvibes订阅到 Rojo订阅到 Yahoo!订阅到 帮看网订阅到QQ邮箱使用手机阅读IM提醒
  • 软件测试的核心价值是什么?
    ASM学习,摘引自http://qa.taobao.com/?p=6266功能点算法及在软件测试中的应用Part2
    ASM学习,摘引自http://qa.taobao.com/?p=6266手持设备测试的探索
    推荐栏目:
    ASM学习,摘引自http://qa.taobao.com/?p=6266论坛——淘测试
    ASM学习,摘引自http://qa.taobao.com/?p=6266黑灯舞会
    ASM学习,摘引自http://qa.taobao.com/?p=62663T交流会-百家讲坛
    ASM学习,摘引自http://qa.taobao.com/?p=6266淘测试电子期刊问卷调查
    ASM学习,摘引自http://qa.taobao.com/?p=6266
      ASM学习,摘引自http://qa.taobao.com/?p=6266

      <noscript></noscript>

      ASM学习,摘引自http://qa.taobao.com/?p=6266Loading...??

  • 热点排行