private static void makeNewClass() throws IOException, CannotCompileException {
ClassPool classPool = ClassPool.getDefault();
CtClass cc = classPool.makeClass("Test");
byte[] bytes = cc.toBytecode();
FileOutputStream fos = new FileOutputStream("/Users/apple/Desktop/Test.class");
fos.write(bytes);
fos.flush();
fos.close();
}
private static void readClassFile() throws IOException, CannotCompileException {
FileInputStream fis = new FileInputStream("/Users/apple/Desktop/JavassitTest.class");
ClassPool classPool = ClassPool.getDefault();
CtClass cc = classPool.makeClass(fis);
System.out.println(Arrays.toString(cc.toBytecode()));
}
private static void byteArrayClassPath() throws IOException, NotFoundException {
FileInputStream fis = new FileInputStream("/Users/apple/Desktop/JavassitTest.class");
String result = "";
byte[] bytes = new byte[1024];
while (fis.read(bytes) != -1) {
result += new String(bytes);
}
ClassPool cp = ClassPool.getDefault();
cp.insertClassPath(new ByteArrayClassPath("JavassistTest", result.getBytes()));
CtClass cc = cp.get("JavassistTest");
System.out.println(cc.getSimpleName());
}
private static void renameAClass() throws IOException, CannotCompileException {
FileInputStream fis = new FileInputStream("/Users/apple/Desktop/JavassitTest.class");
ClassPool classPool = ClassPool.getDefault();
CtClass cc = classPool.makeClass(fis);
cc.setName("JavassistRocks");
FileOutputStream fos = new FileOutputStream("/Users/apple/Desktop/JavassistRocks.class");
fos.write(cc.toBytecode());
fos.flush();
fos.close();
}
private static void insertBefore() throws IOException, NotFoundException, CannotCompileException {
FileInputStream fis = new FileInputStream("/Users/apple/Desktop/JavassitTest.class");
ClassPool classPool = ClassPool.getDefault();
CtClass cc = classPool.makeClass(fis);
CtMethod ctMethod = cc.getDeclaredMethod("main");
ctMethod.insertBefore("System.out.println($1.length);");
cc.setName("JavaassistInsertBefore");
FileOutputStream fos = new FileOutputStream("/Users/apple/Desktop/JavaassistInsertBefore.class");
fos.write(cc.toBytecode());
fos.flush();
fos.close();
}
Identifier | Meanings |
---|---|
$0, $1, $2, ... | this and actual parameters |
$args | An array of parameters. The type of $args is Object[]. |
$$ | All actual parameters. |
$cflow(...) | cflow variable |
$r | The result type. It is used in a cast expression. |
$w | The wrapper type. It is used in a cast expression. |
$sig | An array of java.lang.Class objects representing the formal parameter types. |
$type | A java.lang.Class object representing the formal result type. |
$class | A java.lang.Class object representing the class that declares the method currently edited (the type of $0). |
private static void newMethod() throws IOException, CannotCompileException {
FileInputStream fis = new FileInputStream("/Users/apple/Desktop/JavassitTest.class");
ClassPool classPool = ClassPool.getDefault();
CtClass cc = classPool.makeClass(fis);
CtMethod cm = CtNewMethod.make("public void fuckingWorld(String str){System.out.println(\"Fucking:\" + str);}", cc);
cc.addMethod(cm);
cc.setName("JavassistNewMethod");
FileOutputStream fos = new FileOutputStream("/Users/apple/Desktop/JavassistNewMethod.class");
fos.write(cc.toBytecode());
fos.flush();
fos.close();
}
javassist.Loader searches for classes in a different order from java.lang.ClassLoader. ClassLoader first delegates the loading operations to the parent class loader and then attempts to load the classes only if the parent class loader cannot find them. On the other hand, javassist.Loader attempts to load the classes before delegating to the parent class loader.