Folks, could you please advise how I can rebase existing class so that it doesn't have particular interface in its parents ?
For example
interface One {
fun one(): Unit
}
interface Two {
fun two(): Unit
}
class Test: One, Two {
// implementation of one() and two()
}
val newClass = ByteBuddy()
.rebase(Test::class.java)
.name("com.test.Test2")
.implement(Two::class.java)
.make()
.load(this.javaClass.classLoader, ClassLoadingStrategy.Default.WRAPPER)
.loaded
val inst = newClass.declaredConstructors.first().newInstance()
val isOne = inst is One
Unfortunately isOne
is still true. What am I missing ?
CodePudding user response:
Byte Buddy does not really aim for removing properties. What you can do is to use ASM via the visit method, to remove elements from the byte code.
Or you can declare a new class, define it the way you and name it the same as the class you wanted to change.
CodePudding user response:
I've solved it through creating delegate class like this
val fieldDelegate = "delegate"
val unloaded = ByteBuddy()
.subclass(Any::class.java)
.defineField(fieldDelegate, Test::class.java, Opcodes.ACC_PRIVATE or Opcodes.ACC_FINAL)
.name(Test::class.java.canonicalName "Wrapper")
.implement(Two::class.java)
.defineConstructor(Visibility.PUBLIC)
.withParameters(Test::class.java)
.intercept(MethodCall.invoke(Object::class.java.getConstructor()).andThen(FieldAccessor.ofField(fieldDelegate).setsArgumentAt(0)))
.method(ElementMatchers.isAbstract())
.intercept(MethodDelegation.toField(fieldDelegate))
.make()
val clazz = unloaded
.load(Test::class.java.classLoader, ClassLoadingStrategy.Default.WRAPPER)
.loaded