#javassist
#javassist
Вопрос:
Я играю с javassist (чтобы использовать его позже в проекте), но мне не удается выполнить простое обновление класса. Я пытаюсь вставить код перед методом, но он не выполняется.
У меня есть проект gradle, и я использую версию javassist: ‘3.27.0-GA’.
Учитывая следующий класс:
public class Dummy{
public int dummy(){
return 5;
}
}
Следующий тест завершается с ошибкой, поэтому класс не изменяется:
@Test
public void modifyReturnValueTest() throws NotFoundException, CannotCompileException, IOException {
ClassPool pool = ClassPool.getDefault();
CtClass cc = pool.get("Dummy");
CtMethod m = cc.getDeclaredMethod("dummy");
m.insertBefore("{ if(true) return 3; }");
cc.writeFile();
assertEquals(3, new Dummy().dummy());
}
Я что-то упускаю?
Ответ №1:
Я предполагаю, что когда вы вызываете new Dummy().dummy()
assertEquals(3, new Dummy().dummy());
загрузчик классов загружает исходную версию Dummy
class .
Поскольку вы хотите загрузить / использовать версию, которую вы изменили, представленную CtClass
экземпляром cc
, вы можете вставить следующий фрагмент перед assertEquals
тем, как заставить загрузчик классов загружать измененную версию Dummy
класса вместо этого:
cc.toClass();
тогда утверждение должно быть успешным.
Обратите внимание, что для использования toClass()
выше мы полагаемся на тот факт, что фиктивный класс никогда не загружается перед toClass()
вызовом. (В противном случае это вызовет исключение, загрузчик классов не сможет загрузить две разные версии одного и того же класса одновременно)
Вы можете проверить документацию javassist для получения более подробной информации. Этот раздел может быть особенно полезен http://www.javassist.org/tutorial/tutorial.html#load .