Skip to content

Java Decompiler and its Missing Documentation

April 15, 2011

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.

Advertisements
2 Comments
  1. HI Nick,

    You write:
    “The “line numbers” referred to actually appear to be the line numbers from the .class file.”

    I guess you mean “line numbers in the .java-sourcefile as denoted by the debug-information in the .class file” (or something like that) — at least, that’s how I understand that jd-eclipse derives that information.

    That may also be the reason why the debugger cannot always find the correct line for a breakpoint. If the .class-file was compiled with javac -g:none line-number info is not present in the .class file.

  2. mchr3k permalink

    I have released a companion plugin which fixes the line numbers issue and makes it easier to switch between real and decompiled source: http://mchr3k-coding.blogspot.co.uk/2012/07/realignment-for-jd-eclipse.html

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: