Переопределить нестатические методы
Я пытаюсь переопределить простой нестатический метод, но получаю исключение:
Exception in thread "main" java.lang.UnsupportedOperationException: class redefinition failed: attempted to change the schema (add/remove fields)
Классы:
class Source {
def hello(name: String): String = ""
}
class Target {
def hello(name: String): String = "Hello" + name + "!"
}
Вызов:
new ByteBuddy()
.rebase(classOf[Source])
.method(ElementMatchers.named("hello"))
.intercept(MethodDelegation.to(new Target))
.make()
.load(classOf[Source].getClassLoader, ClassReloadingStrategy.fromInstalledAgent())
.getLoaded
.newInstance()
.hello("World")
Вышеуказанные классы являются классами scala, но они компилируются в стандартные классы java.
Как правильно переопределить метод?
2 ответа
То, что вы пытаетесь сделать, в настоящее время не поддерживается JVM, вы не можете добавлять или удалять поля или методы из любого класса, что является косвенным следствием перебазирования.
Вместо этого вы можете переопределить класс с помощью ByteBuddy::redefine
, Таким образом, Byte Buddy заменяет исходную реализацию вместо сохранения ее для возможного вызова. Чтобы сделать это, вам также нужно делегировать метод без сохранения состояния (начальный) следующим образом:
public class Target {
public static String hello() {
return "Hello" + name + "!"
}
}
с делегацией: MethodDelegation.to(Target.class)
, Это необходимо, потому что в противном случае Байту Бадди потребуется добавить поле в инструментированный класс для хранения экземпляра делегирования, что невозможно при переопределении.
В качестве альтернативы, посмотрите на Advice
класс, который позволяет вам встроить код в то, что совместимо с перебазированием, где сохраняется оригинальная реализация.
Эта проблема github ( https://github.com/raphw/byte-buddy/issues/14), похоже, указывает на то, что byte-buddy не поддерживает классы, скомпилированные scala.