java class is frozen_利用javassit简单操作class文件 1
maven 構(gòu)建工具 pom.xml
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
facfjavaagent
facfjavaagent
1.0
jar
1.6
2.5.1
javassist
javassist
3.1
org.apache.maven.plugins
maven-jar-plugin
agent.AgentApplication
agent.AgentApplication
true
true
org.apache.maven.plugins
maven-compiler-plugin
${compiler.plugin.version}
${jdk.version}
${jdk.version}
UTF-8
Testdemo.java
import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtField;
import javassist.CtMethod;
import javassist.NotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* description:
*
* @author: he QQ: 905845006
* @email: 905845006@qq.com
* @date: 2020/7/15 4:11 PM
*/
public class Testdemo {
private String text = "hello world";
public static void main(String[] args) {
// test1();
test2();
}
/**
* 1. 創(chuàng)建簡單的類
*/
public static void test1() {
//默認的類搜索路徑
ClassPool classPool = ClassPool.getDefault();
//創(chuàng)建一個ctClass對象
CtClass ctClass = classPool.makeClass("com.lwj.mom.base.javassist.Student");
try {
//添加age屬性
ctClass.addField(CtField.make("private int age;", ctClass));
//添加setAge方法
ctClass.addMethod(CtMethod.make("public void setAge(int age){this.age = age;}", ctClass));
//添加getAge方法
ctClass.addMethod(CtMethod.make("public int getAge(){return this.age;}", ctClass));
//將ctClass轉(zhuǎn)換成字節(jié)碼并寫入文件
byte[] byteArray = ctClass.toBytecode();
FileOutputStream output = new FileOutputStream("/Users/heliming/IdeaProjectss/facf/facfjavaagent/src/main/java/Student.class");
output.write(byteArray);
output.close();
System.out.println("文件寫入成功!!!");
} catch (CannotCompileException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 2. 修改jvm加載過的class
*/
public static void test2() {
//默認的類搜索路徑
ClassPool classPool = ClassPool.getDefault();
//創(chuàng)建一個ctClass對象
CtClass ctClass = classPool.makeClass("com.lwj.mom.base.javassist.Student");
//重點
ctClass.stopPruning(true);
try {
//添加age屬性
ctClass.addField(CtField.make("private int age;", ctClass));
//添加setAge方法
ctClass.addMethod(CtMethod.make("public void setAge(int age){this.age = age;}", ctClass));
//添加getAge方法
ctClass.addMethod(CtMethod.make("public int getAge(){return this.age;}", ctClass));
//將ctClass轉(zhuǎn)換成字節(jié)碼并寫入文件
byte[] byteArray = ctClass.toBytecode();//toBytecode會設(shè)置wasPruned為true
FileOutputStream output = new FileOutputStream("/Users/heliming/IdeaProjectss/facf/facfjavaagent/src/main/java/Student.class");
output.write(byteArray);
output.close();
System.out.println("文件寫入成功!!!");
//重點
if(ctClass.isFrozen()){
ctClass.defrost();
}
//這里用pool.get()去獲取ctClass對象,表示默認JVM已經(jīng)加載此類.
ctClass = classPool.get("com.lwj.mom.base.javassist.Student");
ctClass.addField(CtField.make("private String sex;", ctClass));
ctClass.addField(CtField.make("private String name;", ctClass));
byteArray = ctClass.toBytecode();
output = new FileOutputStream("/Users/heliming/IdeaProjectss/facf/facfjavaagent/src/main/java/Student.class");
output.write(byteArray);
output.close();
System.out.println("文件修改成功!!!!");
} catch (CannotCompileException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (NotFoundException e) {
e.printStackTrace();
}
}
}
問題:
jvm加載的類默認被凍結(jié)如果不解凍就修改報錯。
jvm默認對加載的class進行了剪切已提高性能,如果不設(shè)置為不剪切加載的class,就算解凍也會失敗,因為class類已經(jīng)剪切了沒法從新改這個class類了。
可以看出我修改的class可以隨意定義包名,然后把這個class放入對應(yīng)的包下就能找到。
總結(jié)
以上是生活随笔為你收集整理的java class is frozen_利用javassit简单操作class文件 1的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java cellformat_java
- 下一篇: php一句话图片木马过滤_php一句话图