Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get a name of a method parameter using Javassist

Tags:

javassist

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.

like image 934
monnef Avatar asked Dec 01 '13 20:12

monnef


People also ask

How do I change the name of a method in Javassist?

Javassist does not allow to remove a method or field, but it allows to change the name. So if a method is not necessary any more, it should be renamed and changed to be a private method by calling setName () and setModifiers () declared in CtMethod . Javassist does not allow to add an extra parameter to an existing method, either.

How to change a method to a private method in Javassist?

So if a method is not necessary any more, it should be renamed and changed to be a private method by calling setName () and setModifiers () declared in CtMethod . Javassist does not allow to add an extra parameter to an existing method, either.

How to add an extra parameter to a method in Java?

For example, if you want to add an extra int parameter newZ to a method: in a Point class, then you should add the following method to the Point class: void move (int newX, int newY, int newZ) { // do what you want with newZ. move (newX, newY); }

How do I remove a method from a method list in Javassist?

Javassist does not allow to remove a method or field, but it allows to change the name. So if a method is not necessary any more, it should be renamed and changed to be a private method by calling setName () and setModifiers () declared in CtMethod .


2 Answers

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!

like image 197
pabrantes Avatar answered Sep 20 '22 02:09

pabrantes


If you don't actually want the names of the parameters, but just want to be able to access them, you can use "$1, $2, ..." as seen in this tutorial.

like image 20
neon Avatar answered Sep 22 '22 02:09

neon