ByteBuddy - перебазировать уже загруженный класс
У меня есть следующий код, работающий в приложении SpringBoot, и он делает то, что я ожидаю.
TypePool typePool = TypePool.Default.ofClassPath();
ByteBuddyAgent.install();
new ByteBuddy()
.rebase(typePool.describe("com.foo.Bar").resolve(), ClassFileLocator.ForClassLoader.ofClassPath())
.implement(typePool.describe("com.foo.SomeInterface").resolve())
.make()
.load(ClassLoader.getSystemClassLoader());
Он делает так, что класс com.foo.Bar реализует интерфейс com.foo.SomeInterface (который имеет реализацию по умолчанию)
Я бы хотел. используйте приведенный выше код, ссылаясь на класс как Bar.class, не используя строковое представление имени. Но если я сделаю это, я получу следующее исключение.
java.lang.UnsupportedOperationException: class redefinition failed: attempted to change superclass or interfaces
Я полагаю, из-за того, что это вызывает загрузку класса до переопределения. Я только сейчас учусь использовать ByteBuddy.
Я хочу избежать размышлений во время выполнения, добавив интерфейс и реализацию, используя ByteBuddy. У меня есть другой код, который проверяет этот интерфейс.
1 ответ
Это невозможно, не из-за Byte Buddy, но никакому инструменту не разрешено делать это на обычной виртуальной машине. (Существует так называемая виртуальная машина динамического развития кода, которая способна на это).
Если вы хотите избежать проблемы, используйте redefine
скорее тогда rebase
, Всякий раз, когда вы применяете метод, вы теперь заменяете оригинал.
Если это не приемлемо, посмотрите на Advice
класс, который вы можете использовать .visit
-API, чтобы обернуть логику вокруг вашего исходного кода, не заменяя его.