Pages

Sunday, May 8, 2011

Java Decompiler and its Missing Documentation

If you ever need a good decompiler for Java, there are plenty around. Nonetheless, I found one that integrates smoothly with Eclipse, which I’m guessing is not as common. The aptly named Java Decompiler is a newer one that has three parts: a core library (JD-Core), a GUI (JD-GUI) and an Eclipse plugin (JD-Eclipse). The purpose of the first two parts is fairly obvious. There is a core library that implements the decompiler and a GUI application you can use to view decompiled files. The Eclipse plugin is the most novel and interesting piece of the trio, so that’s what I’m going to discuss here.

It sounds like a great plugin, but what does it do?

That’s a good question, and it’s the natural one to ask when you’re looking for such a thing. The JD-Eclipse page makes an effort to help you through installing the promising plugin, but it tells no stories about what functionality it offers. Oddly enough, the page doesn’t even explain what settings are available for the plugin. In fact, it doesn’t even mention that there are any preferences (yet they do exist).
It turns out that JD-Eclipse is quite a nice plugin. It quietly and effectively handles many use cases. There are some quirks with it, but overall it’s a great tool to have around. The official JD-Eclipse website lacks documentation on what to expect when using the tool. To fill that void, here are some of the features of JD-Eclipse that I’ve stumbled upon so far.

Settings


The JD-Eclipse settings panel.
The plugin’s two settings are located in Window –> Preferences –> Java –> Decompiler. The Display line numbers setting is deceitfully obvious. The “line numbers” referred to actually appear to be the line numbers from the .class file. The .class file line numbers are placed to the left of the code in a column of comments. In Listing 1, notice that the first number is the line number in the decompiled source file. Toggling off the Display line numbers setting will remove the .class file line numbers.
86 /*          */   public void setTitle(String title)
87 /*          */   {
88 /* 126 */     this.title = title;
89 /*          */   }
Listing 1 - A snippet of decompiled source code.
The Display metadata setting is useful to keep on. This prompts JD-Eclipse to add a comment to the bottom of each decompiled file identifying precisely which .class file was decompiled, what version of Java was used, and what version of JD-Core was used. The comment will look similar to Listing 2.
/* Location:           C:\eclipse-workspace\library.jar
  * Qualified Name:     com.example.SampleClass
  * Java Class Version: 6 (50.0)
  * JD-Core Version:    0.5.3
  */
Listing 2 - The JD-Eclipse metadata from the bottom of a decompiled source file.
One major caveat to understand with these settings is that they are not instantly applied. Unlike all other Eclipse preferences, you have to restart Eclipse for these to take effect. I recommend just turning both on and leaving them set, which is the default.

When and where does JD-Eclipse do its work for you?

This is the real question I wanted an answer to before I installed it. Here are the scenarios I’ve encountered so far where JD-Eclipse decompiles code automatically for you. I emphasize automatic because that is why JD-Eclipse is a great tool. The designer has done a good job of figuring out when you would need code decompiled and has incorporated that knowledge into the plugin.

Opening a Java type

The most common scenario is when you’re opening a Java type. Specifically, a type for which the source code is absent from the project. There are several ways to do this in Eclipse and they all result in the decompiled source being opened.
As an example, let’s use the JDK classes. Especially if you’re using a licensed JDK like IBM’s, you probably don’t have the source code available in your workspace. But what if you want to look at a method’s implementation in the String class? You certainly do have the compiled JDK code in your workspace and JD-Eclipse can find it and decompile the class automatically. Here is a list of the ways I know of where you could open the String class in Eclipse:
  1. Use the Open Type dialog (Ctrl+Shift+T)
  2. Use the Enterprise Explorer, Package Explorer or Navigator view to drill-down to and open the String class in the included JRE/JDK library.
  3. Hover over the text of the class name “String” in a source file and left-click to open the class.
  4. Open the String class from the result of a Java search.
I’m sure there are other ways to open a class in Eclipse, but this list covers the most common scenarios. In any case, the result is that you can see the source code for the String class, a feat that JD-Eclipse pulls off automatically and silently. The only way you even know that JD-Eclipse was involved is by the display of its signature coffee mug icon beside the class name.

The decompiled java.lang.String class in Eclipse with the JD-Eclipse coffee mug logo.

Debugging

This scenario was the most surprising to me. I expected that when I opened a class with no source code that I would get the decompiled source, but I assumed that’s where JD-Eclipse would stop. Pleasingly, the decompiler also works when debugging. The simple act of stepping into code with no source code present will cause JD-Eclipse to kick in. The debugger will happily then display the decompiled source code and break at the expected line.  Impressive.

The "debug" perspective in Eclipse. The debugger is at a break point in the String class.

When does JD-Eclipse not work for you?

There are some times when JD-Eclipse doesn’t do what I hoped it would. The biggest short-coming I’ve seen so far is that the decompiled code doesn’t always work correctly with the debugger. I’ve had a few times where the debugger breaks at a non-sensical line such as a closing bracket. Why this is, I can’t say for sure. My guess is that the process of compiling and decompiling causes the line numbers to be off slightly. This may not even be the fault of JD-Eclipse, but it’s still a nuisance.
JD-Eclipse also appears to override Eclipse when you actually have source code attached to a library. Even when you’ve configured your project to reference source code for a library, JD-Eclipse always wins out and displays the decompiled code. Ideally, JD-Eclipse should recognize this setting and let the real source code open rather than intervening with its decompiled version.
The other scenario that JD-Eclipse doesn’t cover is JSP files. Unfortunately, I haven’t yet found a way to decompile a compiled JSP. Again, this may be more an issue with Eclipse than JD-Eclipse.

Conclusion

JD-Eclipse is a great tool to have if you work often in Eclipse. What struck me as most enticing about it is how nimbly and stealthy it does its job. Most times, it just does what you want it to do, which is show the source code. Oh, and I didn’t mention that it’s fast. I’ve never noticed a pause while JD-Eclipse is decompiling. The source just opens as if it were right there in my project.

Decompile java code with Cavaj


Decompile java code with Cavaj

Cavaj decompilerDecompilers are used commonly for reconstructing the lost code and is used across different programming languages and in all platforms.The use of decompilers in java programming language is quite high compared to other ones. I have written an article about Java Decompilers last year which talks about the best open-source and commercial decompilers. I missed an important freeware java decompiler called Cavaj which helps you decompile java source code from class files recovering the lost source code.

Cavaj reconstructs the source code with the Class View providing instant access to methods and fields in the form of a tree view. The good thing about Cavaj Java Decompiler is, it doesn’t require you to have Java installed to use the decompiler and it is just a light weight stand-alone application. Cavaj Java decompiler uses Jad as its Java decompiling engine which makes the application light weight and handy. Check it out guyz.