我試圖修改在超類中聲明的方法CtMethod#insertBefore
。但是,Javassist似乎不可能。修改Javassist在超類中聲明的方法
private class AbstractTestDataSource {
public Connection getConnection() throws SQLException {
return connection;
}
}
private class TestDataSource extends AbstractTestDataSource implements DataSource {
public Connection getConnection(String username, String password) throws SQLException {
return connection;
}
// other methods omitted
}
這是我ClassFileTransformer
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
ProtectionDomain protectionDomain, byte[] classfileBuffer)
throws Exception {
if (!className.equals("org/example/TestDataSource")) {
return classfileBuffer;
}
final CtClass ctClass = createCtClass(loader, classfileBuffer);
for (CtMethod method : ctClass.getMethods()) {
if (method.getName().equals("getConnection")) {
System.out.print(method.getName());
System.out.println(method.getSignature());
method.insertBefore("System.out.println(\"foo\");");
}
}
return ctClass.toBytecode();
}
當我打電話getConnection(String, String)
方法,foo
被打印到控制檯,但如果我認爲這種聲明在AbstractTestDataSource
沒有任何反應getConnection()
方法。 我在做什麼錯?
編輯
我可以證實,這兩種方法都儀器,因爲這是被打印到控制檯:
getConnection(Ljava/lang/String;Ljava/lang/String;)Ljava/sql/Connection;
getConnection()Ljava/sql/Connection;
你已經確定insertBefore被調用了兩次,但你沒有檢查它實際被調用的是什麼。嘗試打印方法名稱和描述符。更好的是,看看你是否可以獲得目標類的實際類文件並反彙編它。 – Antimony 2015-04-06 14:34:59
好吧,我想我知道問題在哪裏。超類沒有被修改,因爲在transform方法中,我只能轉換當前加載的一個類。我想我現在的選擇是重新轉換超類或動態覆蓋超類方法。現在嘗試後一種選擇... – Felix 2015-04-06 14:54:54