I'm generating classes with ByteBuddy. In one place, I need to call a static utility method which accepts varargs of type String. My code looks like this:
String[] myStringArray = generateParameters()
MethodCall.invoke(utilsCall)
.with(myStringArray)
This seems to work just fine. While the JVM that generated the code is running, I can create an instance of the generated class via reflection and call the generated method just fine. However, if I call getBytes()
on the generated class and write it to a *.jar file, said file will look like this (after decompilation):
public class MyGeneratedClass {
// $FF: synthetic field
public static String[] methodCall$p1kp7a1;
public void myGeneratedMethod(){
MyUtils.myStaticMethod(methodCall$p1kp7a1)
}
}
Consequently, attempting to load this *.jar file and calling myGeneratedMethod
throws a NullPointerException
, because the synthetic field generated by ByteBuddy was never initialized. In fact, the generated *.class file does not show any traces of the contents of myStringArray
I passed into the method during the initial generation step.
What am I doing wrong? I need to be able to write the generated classes to files and load them in later, with the arguments "baked in".
You are supplying myStringArray
directly. Then, Byte Buddy needs to store it. Instead, you would need to supply the argument from a field or a method where it can be supplied. Alternatively, you can add a field manually (via defineField
) and initialize it manually such that you do not rely on Byte Buddy's initialization.