5

I'm making a tool to dynamically display the sourcecode of running java class. I need a tool to help me on dynamically decompile from a Class Object to String of sourcecode. I know some decompile tools like Jad, DJ decompiler can decompile a .class file but I expect a tool can:

Class<?> c = ..; // get from runtime environment
String sourcecode = **DecompileTool**.decompileClassObject(c);
return sourcecode;

I need such a DecompileTool, anyone knows? Thanks

JerryCai
  • 1,663
  • 4
  • 21
  • 36

4 Answers4

3

I'm not aware of any decompiler that can be used like that.

Indeed, in the general case it is not possible to implement a decompiler that works like that:

  • The Class<?> object that you get from the runtime doesn't provide any way to get to the bytecodes.

  • In order to get hold of the bytecodes, you would need to redo what the classloader does when it locates the ".class" file from the classpath.

  • I don't think there's a way to find out what classloaders are in use ... if you include the possibility of dynamically instantiated classloaders. (And such classloaders are normal practice in (for example) web containers.)

  • In the general case, a classloader will do that in ways that you cannot reproduce ... without reverse engineering and hard-coding the same logic into your decompiler adapter code.

Besides, doing this on the fly is probably pointless, because there is a significant chance that the decompiler will produce source code that isn't compilable.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • Thanks, I wonder is there a way to get .class file path(used in jar file) from Classloader, I found a way like: `Class> c = ...;` `URL url = c.getClassLoader().getResource(classname);` `// use this URL object to locate .class file?` – JerryCai Jul 02 '12 at 04:02
  • 1
    That will usually work, but there are cases where it won't, and others where it doesn't help. One case where it doesn't work is when the resource is embedded in a downloaded file. One case where it doesn't help is when the you are using a JAR file with encrypted class files and a custom classloader that decrypts at load time. – Stephen C Jul 02 '12 at 12:44
2

I don't think that any of these decompilers support this type of ugly interface.

First of all, most decompilers will represent any code in a similar format to the actual compiler, so, an Abstract Syntax Tree. If you are lucky, and the decompiler does have an interface, it will probably be of this type. Handing back a raw String is unlikely to be satisfactory, because how would the person writing the decompiler have any idea as to how you wanted the code formatted (one of the biggest challenges in decompilation is presenting the result to the user!).

Instead, what you should do, is write a little wrapper, that does this properly: on the fly generation of the files that need to be decompiled, sending them through the decompiler, and extracting the result into a String (which you can get immediately if you do clever forking and piping, etc..., but in reality you probably just want to format the output file of the decompiler..)

Kristopher Micinski
  • 7,572
  • 3
  • 29
  • 34
  • Thanks, but as @Stephen C said, maybe there is no way to convert `Class>` to bytecode .class file. :( – JerryCai Jul 02 '12 at 03:50
  • I wonder is there a way to get .class file path(used in jar file) from Classloader, I found a way like: `Class> c = ...;` `URL url = c.getClassLoader().getResource(classname);` `// use this URL object to locate .class file?` – JerryCai Jul 02 '12 at 04:05
0

Try Cavaj Java Decomplier, it may be useful for you.If you aren't satisfied this, try JadClipse with eclipse IDE.

Sai Ye Yan Naing Aye
  • 6,622
  • 12
  • 47
  • 65
0

You can do the followin thing steps

1) You can use decompilers available to decompile the code like

Process p = Runtime.getRuntime().exec("jad /location/CompilesClass.class");
BufferedReader in = new BufferedReader(  
    new InputStreamReader(p.getInputStream()));  
String line = null;  
while ((line = in.readLine()) != null) {  
    System.out.println(line);  
}  

2) Now the Compiled class is converted into .jad extension (Source Code) in the path where the class file was there

3) Now you can read that .jad file by Scanner class of JDK6. Like

        Scanner scanner = new Scanner(new File("locationOfJADFIle")).useDelimiter("\n");

        while(scanner.hasNext()){
            System.out.println(scanner.next());
        }
Bhavik Ambani
  • 6,557
  • 14
  • 55
  • 86
  • thanks. If I got the .class file, I'll use your method. But before that, the biggest problem is how can I find this .class file from `Class>` object? Or, is there a way in java can search and copy out the .class file in the jar by classname? – JerryCai Jul 02 '12 at 04:55