- 浏览: 547377 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (740)
- css (4)
- jquery (8)
- javascript (23)
- html (0)
- uml (0)
- 设计模式 (1)
- 开发工具 (14)
- json (4)
- struts 1.x (3)
- spring (3)
- hibernate (6)
- struts 2.x (17)
- JFreechart (0)
- j2se (48)
- jsp (9)
- flex (22)
- 找工作 (1)
- 技术杂谈 (18)
- 网络编程 (5)
- io流 (1)
- ORACLE (15)
- 报表 (3)
- extjs (11)
- jpbm (2)
- swing (5)
- jspereports (3)
- sql (1)
- linux (15)
- ps (1)
- storm (4)
- hbase (8)
- li (0)
- python (1)
- hive (3)
- 机器学习 (1)
- hdfs (1)
- elasticsearch (1)
- hadoop 2.2 (5)
- hadoop (1)
最新评论
-
Tristan_S:
这个有点意思
ASM -
starryskydog:
程序修改detail band部分的样式 如内容字体大小 ...
使用jasperReport实现动态表头 -
samwong:
Good, so usefule
使用YUI Compressor压缩CSS/JS -
gc715409742:
能够告诉我怎么在web项目中使用YUI Compressor? ...
使用YUI Compressor压缩CSS/JS -
JsonTeye:
您好! 我看你的代码,我现在也在做动态报表,实现功能由用户自己 ...
使用jasperreport动态生成pdf,excel,html
关于java字节码的处理,目前有很多工具,如bcel,asm。不过这些都需要直接跟虚拟机指令打交道。如果你不想了解虚拟机指令,可以采用javassist。javassist是jboss的一个子项目,其主要的优点,在于简单,而且快速。直接使用java编码的形式,而不需要了解虚拟机指令,就能动态改变类的结构,或者动态生成类。
下面通过一个简单的例子,通过javassist来实现如何动态注入代码。
假设,存在类A,如下:
java 代码
public class A {
public void method() {
for (int i = 0; i < 1000000; i++) {
}
System.out.println("method1");
}
}
测试类B如下:
java 代码
public class B {
public static void main(String[] args) {
A a = new A();
a.method();
}
}
现在想统计一下method的执行时间,
默认的实现是修改method:
java 代码
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方法:
java 代码
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();
}
下面通过一个简单的例子,通过javassist来实现如何动态注入代码。
假设,存在类A,如下:
java 代码
public class A {
public void method() {
for (int i = 0; i < 1000000; i++) {
}
System.out.println("method1");
}
}
测试类B如下:
java 代码
public class B {
public static void main(String[] args) {
A a = new A();
a.method();
}
}
现在想统计一下method的执行时间,
默认的实现是修改method:
java 代码
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方法:
java 代码
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();
}
发表评论
-
使用Java调用谷歌搜索
2013-10-19 12:50 902转自:http://yangshangchuan.iteye ... -
走出类加载器迷宫
2013-10-16 14:22 691这是前几天在看类加载器机制时搜到的一篇旧文,网上搜了搜 ... -
Log4j使用
2012-12-05 11:34 784... -
Java的JDBC数据库连接池实现方法
2012-09-14 10:20 743虽然J2EE程序员一般都有现成的应用服务器所带的JDBC数据库 ... -
什么是线程安全和线程不安全
2012-08-23 14:49 795什么是线程安全和线程 ... -
线程运行栈信息的获取
2012-08-23 14:49 833线程运行栈信息的获取 ... -
log4j 获取行号
2012-08-23 14:50 1163log4jjava 今天看log4j的日志,突然注意到log ... -
javassist【动态改字节码】学习三
2012-08-23 14:50 2669这里举个简单的例子,来记录下如何用CtClass创建一个类,并 ... -
javassist【动态改字节码】学习二
2012-08-22 11:53 839写了个例子。 有一个类: Java代码 package ... -
javassist[动态改字节码]学习一
2012-08-22 11:52 905前段时间为了公司里的 ... -
JVM启动参数
2012-08-22 11:51 948一、标准参数 1.-server -client 虚拟机服务器 ... -
利用javaassist修改Class文件
2012-08-22 11:22 1504我们在开发中有时候会遇到这样的问题,就是使用的某个第三方包中的 ... -
JavaMail
2012-08-16 20:03 952在Java EE应用程序中,经常需要发送E-mail。Java ... -
让java变成脚本语言
2012-08-15 12:42 0今天在弄游戏的GM模块,大部分gm命令很简单,只是单纯改 ... -
JavaAgent
2012-08-13 23:43 1278-javaagent 这个JVM参数是JDK 5引进的. j ... -
在Eclipse RCP中实现控制反转(IoC)
2012-08-13 23:13 972摘要:这篇文章描述了 ... -
aop的几种实现方式
2012-08-05 21:14 9491 AOP各种的实现 AOP就是面向切面编程,我们可以从 ... -
Java编程中“为了性能”尽量要做到的一些地方
2012-07-28 21:36 596http://www.iteye.com/magazines/ ... -
java基础拾遗
2012-06-17 10:05 882. 电梯直达 楼主 发表于 2012-1-28 13: ... -
使用 HttpClient 和 HtmlParser 实现简易爬
2012-05-01 17:57 1106使用 HttpClient 和 HtmlParse ...
相关推荐
在本文中,我们将深入探讨Javassist如何实现代码注入,并结合实例`HotPatchDemo`来展示其实现过程。 首先,理解代码注入的基本概念是必要的。代码注入是一种技术,允许在程序运行时向现有代码中插入新的行为或修改...
例如,我们可以通过javaagent在程序启动时注入javassist生成的代码,以实现对目标类的动态增强。以下是一个简单的示例: 1. 创建一个`javaagent`,定义一个`premain`方法,该方法会在JVM启动时被调用: ```java ...
通常,Java Agent用于AOP(面向切面编程)或者性能监控,它可以通过`Premain`方法在JVM启动时注入代码,也可以通过`Agentmain`方法在应用程序启动后注入代码。`java.lang.instrument.Instrumentation`接口提供了与...
因此,使用动态代码生成时需要谨慎,确保生成的代码是可信的。 9. **调试与测试**:由于动态生成的代码不易阅读和理解,调试和测试会变得复杂。开发者需要采取特殊手段,如记录生成的代码或使用专门的调试工具,以...
总结来说,"javassistDemo.zip"是一个实践教程,通过实例演示了如何使用Javaassist库来动态修改Java类,包括插入新的方法和改变方法的实现。这对于理解和掌握Java运行时代码修改技术,尤其是对于那些需要在运行时...
在"javassistDemo"项目中,开发者可能通过以上技术展示了如何使用Javaassist进行类的动态修改和创建,同时也可能演示了如何结合Charles进行网络调试。理解这些知识点对于深入学习Java的动态性、网络调试和AOP编程...
2. **代码注入**:Javaassist 提供了API,使得在运行时向已加载的类中注入代码成为可能。这对于实现诸如事务管理、安全控制等跨切面关注点特别有效。开发者可以通过CtClass的`insertBefore()`、`insertAfter()`和`...
在Struts 2.2及以上版本中,由于框架自身的更新和改进,可能会遇到一些异常,这些问题通常与类加载、依赖注入或者动态方法调用等有关。javassist-3.7.ga.jar 文件是为了解决这些问题而提供的一个辅助工具,它为...
因此,在使用动态编译时,需要权衡效率和安全性,确保对生成的代码进行充分的验证和测试。 5. **工具和库支持**:Java标准库提供了`javax.tools.JavaCompiler`接口,可以直接在运行时编译Java源代码。除此之外,...
如此如此,我们还可以编写测试用的视图,模拟用户的各种操作,从而实现对Presenter的测试-而不需要使用自动化的测试工具 MVP解压缩View时代:以前我们的V层是一个活动或框架实现,大多数情况下,我们的一个页面布局...
在单元测试中,`javassist` 可能被用来动态生成测试类,模拟类的行为,或者在测试框架中注入预期的行为,以便更好地控制测试环境。 以下是对`@Unit`注解处理和`javassist`库使用的一些关键知识点的详细说明: 1. *...
- **动态代码保护**:例如,使用Owasp Java Enforcer或Javassist库,实时监测和阻止不安全的操作。 - **JIT编译器控制**:限制Just-In-Time (JIT) 编译器的行为,避免恶意代码被优化执行。 2. **内存溢出和缓冲区...
1. **字节码注入的原理**:字节码注入通常通过动态代理、ASM、BCEL、Javassist等字节码操作库来实现。这些库允许程序在运行时动态生成或修改字节码,然后通过ClassLoader加载到JVM中,使得修改后的字节码影响目标...
标题"注入到Java世界"暗示我们将探讨如何利用Hook技术对Java应用进行动态修改和调试。在Java中,有几种常见的Hook技术: 1. **Java代理(Java Proxy)**:这是Java标准库提供的一种Hook机制,主要用于创建接口的...
通过Javassist,可以对目标函数动态注入字节码代码,实现函数的备份和修改。 在实际应用中,例如在Tomcat服务器上,可以劫持如Request请求初始化和销毁函数、数据库查询函数以及页面输出函数等关键点。这样,可以...
MCInject:一个修改库,允许将代码轻松注入其他类。 注:该项目已废弃! 我将来可能会回到它,但现在它没有使用。 MCInject 是一个 Minecraft 模组库,它允许任何使用自定义类加载器的模组轻松编辑其他类中的代码...
为了实现代码注入,这里使用了`javassist`库。`javassist`是一个Java字节码操作库,允许我们在运行时修改类或生成新的类。创建一个名为`buildSrc`的模块,该模块基于Groovy开发。在`buildSrc`模块中,定义一个名为`...
学习如何分析和修改字节码,可以提升代码审计的能力,例如使用ASM、BCEL或Javassist等库。 6. **Java代码审计**:代码审计是检查代码以发现潜在安全漏洞的过程。这涉及到对源代码和字节码的深度分析,寻找可能的...
9. **Bytecode操作库**:如ASM、BCEL和Javassist等,可以用于动态生成和修改字节码,实现运行时代码的动态生成和注入。 10. **Spring框架**:Spring的DI(依赖注入)和AOP特性使得Java应用更加灵活,易于扩展。它的...
- 注入代码:利用 `CtMethod.insertBefore()` 或 `CtMethod.insertBefore()` 在方法前后插入自定义的 Java 代码。 - 动态代理:实现接口并生成代理类,用于在调用实际方法前后执行特定逻辑。 - 处理异常:学习如何...