Skip to content

Instantly share code, notes, and snippets.

@khotyn
Created February 22, 2012 16:21
Show Gist options
  • Save khotyn/1885860 to your computer and use it in GitHub Desktop.
Save khotyn/1885860 to your computer and use it in GitHub Desktop.
Javassist学习笔记

Javassist学习笔记

创建一个新类

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();
}

直接从Class文件得到一个CtClass

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()));
}

直接从Class文件得到一个CtClass的另一种方法

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();
}

修改一个类,insertBefore

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

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment