关于java字节码的处理,目前有很多工具,如bcel,jasmin 不过这些都需要直接跟虚拟机指令打交道,就是我们平时用到的bytecode。如果你不想了解虚拟机指令,可以采用javassist。javassist是jboss的一个子项目,其主要的优点,在于简单,而且快速。直接使用java编码的形式,而不需要了解虚拟机指令,就能动态改变类的结构,或者动态生成类。
下面通过一个简单的例子,通过javassist来实现如何动态注入代码。
假设,存在类A,如下:
public class A {
public void method() {
for (int i = 0; i < 1000000; i++) {
}
System.out.println("method1");
}
}
测试类B如下:
public class B {
public static void main(String[] args) {
A a = new A();
a.method();
}
}
现在想统计一下method的执行时间,
默认的实现是修改method:
public void method() {
long start = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
}
System.out.println("method1");
long end = System.currentTimeMillis();
System.out.println(end - start);
}
如果A的方法很多,统计方法的执行时间的代码就会相应的增加。为了减少工作量,通过动态注入代码的形式来实现。
修改B的main方法:
public static void main(String[] args) throws Exception {
//用于取得字节码类,必须在当前的classpath中,使用全称
CtClass ctClass = ClassPool.getDefault().get("org.esoft.A");
//需要修改的方法名称
String mname = "method";
CtMethod mold = ctClass.getDeclaredMethod(mname);
//修改原有的方法名称
String nname = mname + "$impl";
mold.setName(nname);
//创建新的方法,复制原来的方法
CtMethod mnew = CtNewMethod.copy(mold, mname, ctClass, null);
//主要的注入代码
StringBuffer body = new StringBuffer();
body.append("{\nlong start = System.currentTimeMillis();\n");
//调用原有代码,类似于method();($$)表示所有的参数
body.append(nname + "($$);\n");
body.append("System.out.println(\"Call to method "
+ mname
+ " took \" +\n (System.currentTimeMillis()-start) + "
+ "\" ms.\");\n");
body.append("}");
//替换新方法
mnew.setBody(body.toString());
//增加新方法
ctClass.addMethod(mnew);
//类已经更改,注意不能使用A a=new A();,因为在同一个classloader中,不允许装载同一个类两次
A a=(A)ctClass.toClass().newInstance();
a.method();
}
public static void main(String[] args) {
try {
ClassPool pool = ClassPool.getDefault();
pool.insertClassPath("E:\\ScrumWorksEJB");
CtClass cls = pool.get("com.danube.scrumworks.licensing.VerifySignature");
CtClass[] param = new CtClass[2] ;
param[0] = pool.get("java.lang.String");
param[1] = pool.get("java.lang.String");
CtMethod m = cls.getDeclaredMethod("isValidSignature");
m.setBody("{return true;}");
System.out.println("--------11111----");
cls.writeFile("E:\\ScrumWorksEJB");
}catch(Exception e) {
e.printStackTrace();
}
}
分享到:
相关推荐
1、打开一个或者多个*.class文件,XJad反编译后,重命名为*.java文件, 保存至当前文件夹,并在编辑器中打开查看; 2、打开一个文件夹,XJad将该文件夹下所有*.class文件进行反编译,并保存至该文件夹下, 依据包...
java反编译软件,可以将编译后的class文件反编译成java文件
java反编译工具(.class文件反编译成.java文件) 解压后点击exe文件打开工具,点击open菜单选择.class文件执行后即生成.java文件 一直在使用的,方便,系统维护必不可少
编译Java源文件的工具 编译.class文件
java反编译工具反编译.class文件 java反编译工具反编译.class文件java反编译工具反编译.class文件java反编译工具反编译.class文件java反编译工具反编译.class文件
查看java编译后的class文件的反编译工具.rar 使用它就能够查看编译过的代码程序了
将.class文件反编译为.java文件,可以实现将别人的文件反编译后查看里面的代码。
java反编译项目工程,可以将class 文件 进行 修改 重新导包 生成修改后的jar 步骤 1、将需要修改的 jar 包 放入 lib 目录下,并加入项目中 ,选中 jar 右击 选择 add a libray这个时候会看到 jar 的 目录 结构 2、...
很小巧的javaclass反编译工具 只需要把点击exe文件执行 然后点击打开想要反编译的class文件 在对应的目录下就会生成.java的javabean文件 非常好用
JAVA反编译软件(可将class文件反编译为java文件)
java class文件编译,可查看编译文件。
应用于class、java等各种文件的反编译操作,文件小巧易用
java的反编译工具,我已经用了五年,感觉十分好用。现在分享给大家
经测试可使用的反编译工具,将.class反编译成.java文件,使用起来非常方便
可以把class文件反编译为java源码的好东西。
class文件反编译工具,直接打开class文件,不用ide,方便快捷好用!
java反编译 java工具 class文件
jd-gui ,java Class反编译工具 ,java jar反编译工具。经济实惠只要1分。这个是在凑字数。这个是在凑字数。这个是在凑字数。
eclipse打开java类编译后的class文件所在目录批处理文件
class文件反编译工具,class文件编译为Java源代码。查看源码的好工具