1 要修改的目标类
public class Test1 {
public static void main(String[] args) {
Test1 t1 = new Test1();
int result = t1.addNumber(3, 5);
System.out.println("result is: "+result);
}
public int addNumber(int a,int b){
return a*b;
}
}
2 修改二进制class 文件的代码
import java.io.IOException;
import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.NotFoundException;
public class UpdateMethod {
public static void main(String[] args) {
updateMethod();
}
/**
*
* 将最初的代码逻辑编译
* javac /Users/tz/work/mars/src/main/java/com/s/demo/assist/Test1.java
* 运行
* java -classpath /Users/tz/work/s/src/main/java com.s.demo.assist.Test1
* 结果
* result is: 15
* 执行修改二进制文件逻辑后
* 运行新的二进制文件
* java -classpath /Users/tz/work/s/target/classes com.s.demo.assist.Test1
* 结果
* result is: 152
*
*/
public static void updateMethod(){
try {
ClassPool cPool = new ClassPool(true);
//如果该文件引入了其它类,需要利用类似如下方式声明
//cPool.importPackage("java.util.List");
//设置class文件的位置
cPool.insertClassPath("/Users/tz/work/s/target/classes");
//获取该class对象
CtClass cClass = cPool.get("com.s.demo.assist.Test1");
//获取到对应的方法
CtMethod cMethod = cClass.getDeclaredMethod("addNumber");
//更改该方法的内部实现
//需要注意的是对于参数的引用要以$开始,不能直接输入参数名称
cMethod.setBody("{ return $1*$1*$1+$2*$2*$2; }");
//替换原有的文件
cClass.writeFile("/Users/tz/work/s/target/classes");
System.out.println("=======修改方法完=========");
} catch (NotFoundException e) {
e.printStackTrace();
} catch (CannotCompileException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
3 报错 Error: Could not find or load main class
其实是没有找到classpath的根本原因,可以参数指定
将最初的代码逻辑编译
* javac /Users/tz/work/mars/src/main/java/com/s/demo/assist/Test1.java
* 运行
* java -classpath /Users/tz/work/s/src/main/java com.s.demo.assist.Test1
* 结果
* result is: 15
* 执行修改二进制文件逻辑后
* 运行新的二进制文件
* java -classpath /Users/tz/work/s/target/classes com.s.demo.assist.Test1
* 结果
* result is: 152