I am trying to return some fields as a list using bytebuddy. I called Arrays.asList() using MethodCall, but it cannot handle variable length parameters. Are there any other approaches?
public class TestClass {
int a;
int b;
public List<?> getFields(){
throw new RuntimeException("Bytebuddy not work.");
}
}
new ByteBuddy()
.rebase(TypePool.Default.ofSystemLoader().describe("com.test.TestClass").resolve(),
ClassFileLocator.ForClassLoader.ofSystemLoader())
.method(ElementMatchers.named("getFields"))
.intercept(MethodCall.invoke(Arrays.class.getMethod("asList", Object[].class))
.withField("a", "b"))
.make()
.load(ClassLoader.getSystemClassLoader(), ClassLoadingStrategy.Default.INJECTION)
.getLoaded();
TestClass testTarget = new TestClass();
LOG.info("result : {}", testTarget.getFields());
error:
Exception in thread "main" java.lang.ExceptionInInitializerError Caused by: java.lang.IllegalStateException: public static java.util.List java.util.Arrays.asList(java.lang.Object[]) does not accept 2 arguments at net.bytebuddy.implementation.MethodCall$Appender.toStackManipulation(MethodCall.java:3537) at net.bytebuddy.implementation.MethodCall$Appender.apply(MethodCall.java:3506) at net.bytebuddy.dynamic.scaffold.TypeWriter$MethodPool$Record$ForDefinedMethod$WithBody.applyCode(TypeWriter.java:708) at net.bytebuddy.dynamic.scaffold.TypeWriter$MethodPool$Record$ForDefinedMethod$WithBody.applyBody(TypeWriter.java:693) at net.bytebuddy.dynamic.scaffold.TypeWriter$MethodPool$Record$ForDefinedMethod.apply(TypeWriter.java:600) at net.bytebuddy.dynamic.scaffold.TypeWriter$Default$ForInlining$WithFullProcessing$RedefinitionClassVisitor.onVisitEnd(TypeWriter.java:5022) at net.bytebuddy.utility.visitor.MetadataAwareClassVisitor.visitEnd(MetadataAwareClassVisitor.java:323) at net.bytebuddy.jar.asm.ClassReader.accept(ClassReader.java:722) at net.bytebuddy.jar.asm.ClassReader.accept(ClassReader.java:401) at net.bytebuddy.dynamic.scaffold.TypeWriter$Default$ForInlining.create(TypeWriter.java:3827) at net.bytebuddy.dynamic.scaffold.TypeWriter$Default.make(TypeWriter.java:2166) at net.bytebuddy.dynamic.scaffold.inline.RebaseDynamicTypeBuilder.make(RebaseDynamicTypeBuilder.java:252) at net.bytebuddy.dynamic.scaffold.inline.AbstractInliningDynamicTypeBuilder.make(AbstractInliningDynamicTypeBuilder.java:123) at net.bytebuddy.dynamic.DynamicType$Builder$AbstractBase.make(DynamicType.java:3595) at net.bytebuddy.dynamic.DynamicType$Builder$AbstractBase$Delegator.make(DynamicType.java:3819) at
In this case of a more complex method body, I would recommend you to write the code in Java and use either a MethodDelegation
or an Advice
to address the issue in code and then link your method.
Alternatively, you can use a StackManipulation
and construct the method from single blocks of code. In this case, you would need to construct an array first and then supply this array to the method as varargs does not exist on the byte code level.