`
can_do
  • 浏览: 263498 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

通过javassist向编译后的指定类中的方法注入时间戳

阅读更多
实现步骤如下:
1.javac -cp .;./javassist.jar JassistTiming.java

2.javac StringBuilder.java

3.java StringBuilder 1000 2000 4000 8000 16000
Constructed string of length 1000
Constructed string of length 2000
Constructed string of length 4000
Constructed string of length 8000
Constructed string of length 16000

4.java -cp .;./javassist.jar JassistTiming StringBuilder buildString
begin to main of JassistTiming
begin to addTiming
Interceptor method body:
{
long start = System.currentTimeMillis();
java.lang.String result = buildString$impl($$);
System.out.println("Call to method buildString took " +
(System.currentTimeMillis()-start) + " ms.");
return result;
}
Added timing to method StringBuilder.buildString

5.java StringBuilder 1000 2000 4000 8000 16000

扩展:如果需要对指定的jar包中的某个类的方法注入时间戳的话,可按如下方式执行。
6.java -cp .;./javassist.jar;apusic.jar;javaee.jar JassistTiming com.apusic.web.http.ConnectionHandler doTrace

其中:
(1)需要提供javassist的jar包javassist.jar,
(2)在构造指定jar包的类时,可能需要引入第三方jar包,如:javaee.jar
(3)指定要注入的类的包路径,如:com.apusic.web.http.ConnectionHandler
(4)指定要注入的类的方法名,不需要带参数,仅方法名标识。
(5)注意使用-cp时,要指定当前目录【.】。

7.最后:向方法中注入时间戳可用于跟踪某个方法执行耗时的统计,可作为分析调优的诊断方法。

8.说明:
(1)javassist去http://www.jboss.org/javassist下载;
(2)JassistTiming.java代码清单:
**************************************
import javassist.CtClass;
import javassist.CtMethod;
import javassist.CtNewMethod;
import javassist.ClassPool;
import javassist.CannotCompileException;
import javassist.NotFoundException;
import java.io.IOException;

public class JassistTiming
{
    public static void main(String[] argv) {
  System.out.println("begin to main of JassistTiming");
        if (argv.length == 2) {
            try {
              
                // start by getting the class file and method
                CtClass clas = ClassPool.getDefault().get(argv[0]);
                if (clas == null) {
                    System.err.println("Class " + argv[0] + " not found");
                } else {
                  
                    // add timing interceptor to the class
                    addTiming(clas, argv[1]);
                    clas.writeFile();
                    System.out.println("Added timing to method " +
                        argv[0] + "." + argv[1]);
                  
                }
              
            } catch (CannotCompileException ex) {
                ex.printStackTrace();
            } catch (NotFoundException ex) {
                ex.printStackTrace();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
          
        } else {
            System.out.println("Usage: JassistTiming class method-name");
        }
    }
  
    private static void addTiming(CtClass clas, String mname)
        throws NotFoundException, CannotCompileException {

  System.out.println("begin to addTiming");
      
        //  get the method information (throws exception if method with
        //  given name is not declared directly by this class, returns
        //  arbitrary choice if more than one with the given name)
        CtMethod mold = clas.getDeclaredMethod(mname);
      
        //  rename old method to synthetic name, then duplicate the
        //  method with original name for use as interceptor
        String nname = mname+"$impl";
        mold.setName(nname);
        CtMethod mnew = CtNewMethod.copy(mold, mname, clas, null);
      
        //  start the body text generation by saving the start time
        //  to a local variable, then call the timed method; the
        //  actual code generated needs to depend on whether the
        //  timed method returns a value
        String type = mold.getReturnType().getName();
        StringBuffer body = new StringBuffer();
        body.append("{\nlong start = System.currentTimeMillis();\n");
        if (!"void".equals(type)) {
            body.append(type + " result = ");
        }
        body.append(nname + "($$);\n");
      
        //  finish body text generation with call to print the timing
        //  information, and return saved value (if not void)
        body.append("System.out.println(\"Call to method " + mname +
            " took \" +\n (System.currentTimeMillis()-start) + " +
            "\" ms.\");\n");
        if (!"void".equals(type)) {
            body.append("return result;\n");
        }
        body.append("}");
      
        //  replace the body of the interceptor method with generated
        //  code block and add it to class
        mnew.setBody(body.toString());
        clas.addMethod(mnew);
      
        //  print the generated code block just to show what was done
        System.out.println("Interceptor method body:");
        System.out.println(body.toString());
    }
}
**************************************
(3)StringBuilder.java代码清单:
**************************************
public class StringBuilder
{
    private String buildString(int length) {
        String result = "";
        for (int i = 0; i < length; i++) {
            result += (char)(i%26 + 'a');
        }
        return result;
    }
  
    public static void main(String[] argv) {
        StringBuilder inst = new StringBuilder();
        for (int i = 0; i < argv.length; i++) {
            String result = inst.buildString(Integer.parseInt(argv[i]));
            System.out.println("Constructed string of length " +
                result.length());
        }
    }
}
**************************************
分享到:
评论

相关推荐

    java 反编译工具 jboss-javassist

    5. **生成和加载类**:最后,使用`CtClass`的`toClass()`方法将修改后的字节码加载到JVM中。 对于初学者,可以通过网上的教程、文档或者示例代码来快速上手。遇到问题时,可以查阅Javassist的官方文档,或者在相关...

    Javassist代码注入

    代码注入是一种技术,允许在程序运行时向现有代码中插入新的行为或修改现有行为,而无需重新编译或重启应用程序。这在软件维护和更新时非常有用,因为它减少了停机时间。 Javassist的核心类是`ClassPool`,` ...

    javassist官方手册(中文)

    Point 的成员方法可以通过 CtNewMethod 的工厂方法创建出来并通过 CtClass 的 addMethod() 方法添加到 Point 类中。 五、冻结类 如果一个 CtClass 对象通过 writeFile(), toClass(), 或 toBytecode() 方法被转换为...

    javassistDemo.zip

    1. **静态方法注入**:Javaassist允许开发者向类中添加新的静态方法,或者修改已有的静态方法。这在需要在运行时添加额外功能,比如日志记录、性能监控等场景下非常有用。 2. **方法体替换**:另一个可能的示例是...

    javassist-3.23.1-GA-API文档-中文版.zip

    赠送jar包:javassist-3.23.1-GA.jar; 赠送原API文档:javassist-3.23.1-GA-javadoc.jar; 赠送源代码:javassist-3.23.1-GA-sources.jar; 赠送Maven依赖信息文件:javassist-3.23.1-GA.pom; 包含翻译后的API文档...

    javassist+jd-gui

    1. **类的加载与操作**:它可以加载类到内存中,并且提供了丰富的 API 来访问和修改类的信息,包括类名、方法、字段等。 2. **字节码生成**:允许开发者使用类似 Java 的语法生成新的类或者方法的字节码,无需关注...

    javassist-3.20.0-GA.zip

    在Javassist中,`CtConstructor`, `CtField`等类分别代表构造函数和字段,它们提供了与方法类似的API,使得对这些元素的修改变得简单。同时,`CtBehavior`类作为方法和构造函数的基类,提供了一些通用的操作接口。 ...

    javassist demo

    你可以指定方法的返回类型、参数类型、方法体等。Javaassist允许使用Java源代码字符串或字节码来定义方法体。 5. **修改方法**:通过`CtMethod`对象,可以修改类中已存在的方法。例如,你可以使用`setBody()`来替换...

    Javassist学习手册

    - **生成类文件**: 使用 `CtClass.writeFile()` 方法将修改后的类写回到磁盘上的 `.class` 文件中。 - **加载为 Java 类**: 使用 `CtClass.toClass()` 方法可以将 `CtClass` 对象加载成 Java 类 (`java.lang.Class`...

    jboss-javassist和JByteMode整合包

    具体来说,可以将JByteMode用于反编译.jar包中的类,获取其源代码,然后利用Javassist修改这些源代码,最后再重新生成字节码并加载到Java虚拟机中。这样的流程在处理复杂的需求,如热更新、插件系统或者代码增强时...

    javaagent+javassist

    例如,我们可以通过javaagent在程序启动时注入javassist生成的代码,以实现对目标类的动态增强。以下是一个简单的示例: 1. 创建一个`javaagent`,定义一个`premain`方法,该方法会在JVM启动时被调用: ```java ...

    javassistDemo

    6. **AOP编程**:Javaassist与AOP(面向切面编程)结合,可以在不修改源代码的情况下,向代码中注入横切关注点,如日志记录、事务管理等。通过定义切点和切面,可以实现灵活的代码结构和解耦。 7. **热部署**:在...

    开发工具 javassist-3.21.0-GA

    开发工具 javassist-3.21.0-GA开发工具 javassist-3.21.0-GA开发工具 javassist-3.21.0-GA开发工具 javassist-3.21.0-GA开发工具 javassist-3.21.0-GA开发工具 javassist-3.21.0-GA开发工具 javassist-3.21.0-GA开发...

    javassist-3.21.0-GA-API文档-中文版.zip

    赠送jar包:javassist-3.21.0-GA.jar; 赠送原API文档:javassist-3.21.0-GA-javadoc.jar; 赠送源代码:javassist-3.21.0-GA-sources.jar; 赠送Maven依赖信息文件:javassist-3.21.0-GA.pom; 包含翻译后的API文档...

    javassist-3.19.0-GA-API文档-中文版.zip

    赠送jar包:javassist-3.19.0-GA.jar; 赠送原API文档:javassist-3.19.0-GA-javadoc.jar; 赠送源代码:javassist-3.19.0-GA-sources.jar; 赠送Maven依赖信息文件:javassist-3.19.0-GA.pom; 包含翻译后的API文档...

    agent+javassist例子

    通常,Java Agent用于AOP(面向切面编程)或者性能监控,它可以通过`Premain`方法在JVM启动时注入代码,也可以通过`Agentmain`方法在应用程序启动后注入代码。`java.lang.instrument.Instrumentation`接口提供了与...

    javassist-3.27.0-GA-API文档-中英对照版.zip

    赠送jar包:javassist-3.27.0-GA.jar; 赠送原API文档:javassist-3.27.0-GA-javadoc.jar; 赠送源代码:javassist-3.27.0-GA-sources.jar; 赠送Maven依赖信息文件:javassist-3.27.0-GA.pom; 包含翻译后的API文档...

    javassist-3.18.1-GA-API文档-中文版.zip

    赠送jar包:javassist-3.18.1-GA.jar; 赠送原API文档:javassist-3.18.1-GA-javadoc.jar; 赠送源代码:javassist-3.18.1-GA-sources.jar; 赠送Maven依赖信息文件:javassist-3.18.1-GA.pom; 包含翻译后的API文档...

    javassist-3.24.0-GA-API文档-中文版.zip

    赠送jar包:javassist-3.24.0-GA.jar; 赠送原API文档:javassist-3.24.0-GA-javadoc.jar; 赠送源代码:javassist-3.24.0-GA-sources.jar; 赠送Maven依赖信息文件:javassist-3.24.0-GA.pom; 包含翻译后的API文档...

    Javassist18版20版22版的jar包

    - 类的动态修改:Javassist提供了一种简单的方式来修改类的方法、字段,甚至可以在运行时添加新的方法或字段。 - 字节码操作:它允许用户通过CtClass接口来操作字节码,CtClass对象代表一个类的字节码表示。 - ...

Global site tag (gtag.js) - Google Analytics