4

I am currently working on a project which demands me to decompile a .class file to java file programmatically. I.E. I have a program that should read a class file and decompile it and the resultant java source code is written into a file. Please help me out to do it.
EDIT: I am completely new to the world of decompilers. I have gone through a few APIs, but i don't know precisely how to use and which one to use. Any sort of help will be really appreciable
EDIT:
I tried using:

import com.strobel.decompiler.*;
import java.io.*;
public class JavaDecode {
public static void main(String[] args)throws Exception {
decompileee();
}

private static void decompileee()throws Exception
{
final DecompilerSettings settings = DecompilerSettings.javaDefaults();
final FileOutputStream stream = new FileOutputStream("C:/jp/decompiled.java");
final OutputStreamWriter writer = new OutputStreamWriter(stream); 
Decompiler.decompile("C:/jp/X.class",
new PlainTextOutput(writer),
settings
);
System.out.println("Success");
}
}

But the above code simply created a file called "decompiled.java" in the scpecified directory. But the file is an empty file.

user3425778
  • 53
  • 1
  • 7
  • 3
    There is not nearly enough information for us to be able to help you with this. What program did you try? How did you try it out? What results did you expect? What results did you get? – DanielBarbarian Apr 22 '14 at 11:18
  • This is far from easy - You should find an existing open source decompiler and use the code. – assylias Apr 22 '14 at 11:23

2 Answers2

7

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
}
Mike Strobel
  • 25,075
  • 57
  • 69
  • i have used the code provided by you. The exact code that i have used is in the edited section of this question. But the code simply generates an empty file in the specified directory. Any help will be appreciable. – user3425778 Apr 22 '14 at 16:16
  • The code you wrote isn't the same. My code has `stream` and `writer` declared in a `try` resource statement, which means `close()` gets called, which flushes the buffer. Try closing your writer and stream manually. – Mike Strobel Apr 22 '14 at 18:58
  • when i try to use the code exactly as given by you i get an error: try-with-resources is not supported in -source 1.6 (use -source 7 or higher to enable try-with-resources) – user3425778 Apr 22 '14 at 19:05
  • I edited my answer to show you how to close the resources manually. – Mike Strobel Apr 22 '14 at 19:08
  • This really helped me in a big way. Thanks. – arunken Nov 20 '19 at 11:38
0

After 5 minutes searching on Google, here's where to start:

  • De-compiling is complicated task (just like compiling). So you will likely need an external library for this taks. As with any libraries, some are good, others aren't and you must evaluate which library will fit your needs. Some libraries are http://jd.benow.ca/ (the first hit on Google) and https://github.com/alexkasko/krakatau-java (the first hit on Maven).
  • Try to evaluate which library you want to use (What are your requirements? What are the features of the library?). And then try to use the library. If you ran into any problems with a certain library, feel free to ask.

Especially https://github.com/alexkasko/krakatau-java seems to be pretty easy (from the README on GitHub):

List<String> classes = Arrays.asList("foo.bar.Baz1", "foo.bar.Baz2")
List<File> classpath = ...
File outputDir = new File("out");
KrakatauLibrary krakatau = new KrakatauLibrary().
krakatau.decompile(classpath, classes, outputDir);
Thomas Uhrig
  • 30,811
  • 12
  • 60
  • 80