Get a name of a method parameter using Javassist
javassist
Solution
It is indeed possible to retrieve arguments' names, but only if the code has been compiled with debug symbols otherwise you won't be able to do it.
To retrieve this information you have to access the method's local variable table. For further information about this data structure I suggest you to check section 4.7.13. The LocalVariableTable Attribute of the jvm spec. As I usually say, JVM spec may look bulky but it's an invaluable friend when you're working at this level!
Accessing the local variable table attribute of your ctmethod
CtMethod method = .....;
MethodInfo methodInfo = method.getMethodInfo();
LocalVariableAttribute table = methodInfo.getCodeAttribute().getAttribute(javassist.bytecode.LocalVariableAttribute.tag);
You now have the the local variable attribute selected in `table` variable.
Detecting the number of localVariables
int numberOfLocalVariables = table.tableLenght();
Now keep in mind two things regarding the number in `numberOfLocalVariables`:
- 1st: local variables defined inside your method's body will also be accounted in tableLength();
- 2nd: if you're in a non static method so will be `this` variable.
The order of your local variable table will be something like:
`|this (if non static) | arg1 | arg2 | ... | argN | var1 | ... | varN|`
Retriving the argument name
Now if you want to retrieve, for example, the arg2's name from the previous example, it's the 3rd position in the array. Hence you do the following:
// remember it's an array so it starts in 0, meaning if you want position 3 => use index 2
int frameWithNameAtConstantPool = table.nameIndex(2);
String variableName = methodInfo.getConstPool().getUtf8Info(frameAtConstantPool)
You now have your variable's name in `variableName`.
Side Note: I've taken you through the scenic route so you could learn a bit more about Java (and javassists) internals. But there are already tools that do this kind of operations for you, I can remember at least one by name called paranamer. You might want to give a look at that too.
Hope it helped!
Problem
I have a `CtMethod` instance, but I don't know how to get names of parameters (not types) from it. I tried `getParameterTypes`, but it seems it returns only types. I'm assuming it's possible, because libraries I'm using don't have sources, just class files and I can see names of method parameters in IDE.