How to "Decompile" Java Class Files

How do I decompile Java class files?

Update February 2016:

www.javadecompilers.com lists JAD as being:

the most popular Java decompiler, but primarily of this age only. Written in C++, so very fast.

Outdated, unsupported and does not decompile correctly Java 5 and later

So your mileage may vary with recent jdk (7, 8).

The same site list other tools.

And javadecompiler, as noted by Salvador Valencia in the comments (Sept 2017), offers a SaaS where you upload the .class file to the cloud and it returns you the decompiled code.


Original answer: Oct. 2008

  • The final release of JSR 176, defining the major features of J2SE 5.0 (Java SE 5), has been published on September 30, 2004.
  • The lastest Java version supported by JAD, the famous Java decompiler written by Mr. Pavel Kouznetsov, is JDK 1.3.
  • Most of the Java decompilers downloadable today from the Internet, such as “DJ Java Decompiler” or “Cavaj Java Decompiler”, are powered by JAD: they can not display Java 5 sources.

Java Decompiler (Yet another Fast Java decompiler) has:

  • Explicit support for decompiling and analyzing Java 5+ “.class” files.
  • A nice GUI:

screenshot

It works with compilers from JDK 1.1.8 up to JDK 1.7.0, and others (Jikes, JRockit, etc.).

It features an online live demo version that is actually fully functional! You can just drop a jar file on the page and see the decompiled source code without installing anything.

decompile a .class file programmatically

Procyon includes a Java decompiler framework. It's written in Java, and it can be called as a library. There's not much documentation yet, but I am the author, and I can assist you if you run into trouble--just contact me on BitBucket.

A simple example of how to decompile java.lang.String:

final DecompilerSettings settings = DecompilerSettings.javaDefaults();

try (final FileOutputStream stream = new FileOutputStream("path/to/file");
final OutputStreamWriter writer = new OutputStreamWriter(stream)) {

Decompiler.decompile(
"java.lang.String",
new PlainTextOutput(writer),
settings
);
}
catch (final IOException e) {
// handle error
}

You can also pass a .class file path to the decompile() method instead of a class name.

If you're not using Java 7, make sure to flush/close your I/O resources manually, e.g.:

try {
final FileOutputStream stream = new FileOutputStream("path/to/file");

try {
final OutputStreamWriter writer = new OutputStreamWriter(stream);

try {
Decompiler.decompile(
"java.lang.String",
new PlainTextOutput(writer),
DecompilerSettings.javaDefaults()
);
}
finally {
writer.close();
}
}
finally {
stream.close();
}
}
catch (final IOException e) {
// handle error
}

How do I decompile a java class file?

I'd start by investigating the class file format. Building something to parse its structure and jump in from there.

When you eventually write the code for handling code attributes in the class file, all of the bytecode for a given method will be in an array. From there you'd start applying the JVM specification for how to decompile specific instructions.

There are also libraries that provide much of this functionality already and can help you bootstrap yourself.

How to open *.class files with decompiler by default in Eclipse?

In File Associations below ".class", you will find another ".class without source". Set your decompiler as default in that. Class files should open in the decompiler now.

How to decompile a jar into .java files from command prompt

The JD-CMD GitHub project claims to be able to do so. However, most people I know use JD-GUI.

JD-Core is a library that reconstructs Java source code from one or more “.class” files. JD-Core may be used to recover lost source code and explore the source of Java runtime libraries. New features of Java 5, such as annotations, generics or type “enum”, are supported. JD-GUI and JD-Eclipse include JD-Core library.

I should include that when a source file is compiled, things like the variable assignment and the names of those variables are changed. Similarly, syntactic sugar is changed into what it actually is (such as x += i turns into x = x + i).

Convert .class to .java

Invoking javap to read the bytecode

The javap command takes class-names without the .class extension. Try

javap -c ClassName

Converting .class files back to .java files

javap will however not give you the implementations of the methods in java-syntax. It will at most give it to you in JVM bytecode format.

To actually decompile (i.e., do the reverse of javac) you will have to use proper decompiler. See for instance the following related question:

  • How do I "decompile" Java class files?


Related Topics



Leave a reply



Submit