Я пытаюсь изменить метод с CtMethod#insertBefore
, который объявлен в суперклассе. Однако с Джавасистом это кажется невозможным.Измените метод, объявленный в суперклассе с помощью 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
выводится на консоль, но если я называю getConnection()
метод, объявленный в AbstractTestDataSource
ничего не происходит. Что я делаю неправильно?
Редактировать
Я могу подтвердить, что оба метода инструментальными, потому что это то, что выводится на консоль:
getConnection(Ljava/lang/String;Ljava/lang/String;)Ljava/sql/Connection;
getConnection()Ljava/sql/Connection;
Вы определили, что insertBefore вызывается дважды, но вы не проверили, на что он фактически вызван. Попробуйте распечатать имя и дескриптор метода. Еще лучше, посмотрите, можете ли вы получить фактический файл класса для целевого класса и разобрать его. – Antimony
Хорошо, я думаю, я знаю, где проблема. Суперкласс не изменяется, потому что в методе преобразования я могу преобразовать только один класс, который в настоящее время загружен. Я думаю, что теперь мои варианты - либо перестроить суперкласс, либо динамически переписать метод суперкласса. Попробовав последний вариант сейчас ... – Felix