既に実装済みの処理を変更したい。- javassit 2007/11/23

そんなことは滅多にないと思うけど、既に実装した処理の動作を変更したい場合、javassitがいいのかなぁ。

それで、前回、書いたコードをベースに、既存の処理を変更するためのひとつの方法です。

まず、該当アプリケーションのmainをを呼び出すmainを用意して、そこで処理を変更したいクラスのメソッドを置き換えるということをしています。

で、うまくいくとこの処理以降のクラスは変更が適用されます。
クラスローダーのことは考慮に入れてないので、クラスローダーをごりごり使っている場合は自信がありません....



下記のコードでは、org.apache.commons.lang.StringUtilsの処理を変更しています。

該当アプリケーションクラス

package test_javassist;

import org.apache.commons.lang.StringUtils;

public class Main {

public static void main(String[] args) {

String a = "aaaa";
System.out.println(StringUtils.isEmpty(a));

}

}


置き換えクラス

package test_javassist;

import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.NotFoundException;

public class MyMain {

/*
* !!!! static !!!!
*/
static {
ClassPool cp = ClassPool.getDefault();
CtClass cc = null;
try {
cc = cp.get("org.apache.commons.lang.StringUtils");
CtMethod m = cc.getDeclaredMethod("isEmpty");
// 処理を上書き
m.setBody("return true;");
// このコードはテスト
m.insertBefore("{ System.out.println(\"o_o! Hello.say():\"); }");
// freeze!!
cc.toClass();

} catch (NotFoundException e) {
e.printStackTrace();
} catch (CannotCompileException e) {
e.printStackTrace();
}

}

public static void main(String[] args) {
Main.main(args);
}

}

: