From what i know, java cannot retrieve anything inside method. so i using option -g or -g:vars in javac.
for e.g :
class Test {
int a=0;
void method(boolean boo){
String b;
try
{
new Thread().sleep(1000);
}
catch(InterruptedException e){}
JOptionPane.showMessageDialog(null,"test");
BufferedImage image=ImageIO.read(new File("C:\\file.png"));
}
}
So, i use BCEL to retrieve local variable.
import org.apache.bcel.classfile.*;
import org.apache.bcel.Repository;
class javap
{
public static void main(String[]args)
{
try
{
JavaClass jc = Repository.lookupClass("test");
ConstantPool constantPool = jc.getConstantPool();
Method [] method=jc.getMethods();
for (Method m : method)
{
LocalVariableTable lvt=m.getLocalVariableTable();
LocalVariable[] lv=lvt.getLocalVariableTable();
for(LocalVariable l : lv)
{
System.out.println(l.getName()+" : "+l.getSignature());
}
}
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
}
But it doesn't work if variable is not initialized like String b
. Additionally I want to track constructor calls like new Thread()
or new File()
as well as invocations of static methods and inside intialize inside JFileChooser
like new File
and JOptionPane
too. So I want to see in output Thread
, String b
, JOptionPane
, ImageIO
, and File
.
What should I do, to make them are printed in my program?
You simply cannot get the
b
variable, because java compilers (at least javac and ecj) do not put it into the generated class file at all: if variable is not assigned, no variable slot is allocated and it's not stored in the LocalVariableTable. You can create unused variable with longer name likeString blahblah;
, compile the class, open the compiled .class-file in text editor and search forblahblah
string. You will not found it. So BCEL cannot help you to find the variable which is absent.If you want to track new objects creation and static methods invocation, you can do it scanning the method bytecode. The easiest way to do it with BCEL is to utilize the
MethodGen
(even though you don't want to generate the new method). Here's the full code:The output is the following:
Note that you have
java/lang/Thread
twice, becausenew Thread()
is catched as object creation andThread.sleep()
is catched as static method invocation.