Переопределить нестатические методы

Я пытаюсь переопределить простой нестатический метод, но получаю исключение:

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.

Другие вопросы по тегам