0

The result class file compiled by eclipse and the traditional "javac" command is different. So I want to compile the Java source code in eclipse to get its special output. Also, this output can only be opened by eclipse itself(At least I don't know other ways to open it). However, it's a tough work to open so many files and copy the content to the notepad.

So is there any other way to read the class file generated by eclipse automatically? I guess there are some commands in console to use eclipse and output the result automatically?

Thanks.

vijay
  • 2,646
  • 2
  • 23
  • 37
zzy
  • 751
  • 1
  • 13
  • 25

2 Answers2

2

You can invoke the Eclipse compiler yourself from command line in the same way you use javac: you need the ECJ jar. For example, you can compile a class with:

java -jar ecj-4.2.2.jar hello.java

This can be easily automated if you need, there are some tips on using ECJ and especially for compiling programmatically and ant compiling on this page.

You can use the compiler from the eclipse packages, or get it directly separated from the Eclipse downloads. At the time of this writing, the current latest release is 4.3 and the ECJ compiler can be found on the Eclipse 4.3.0 download page. Look for the JDT Core Batch Compiler package.

From the comments of the other answer, it seems that you need to display the compiled bytecodes, you can invoke javap after the compilation:

javap -c -p -s -v hello

Edit : show compiled class

I was wondering if / how to get a class dump in the same way Eclipse can show it. There is no way as easy as for invoking the eclipse compiler, but I have found a mean anyway by reusing Eclipse internal classes together with a minimal class wrapper.

ClassDump.java

import java.io.RandomAccessFile;
import java.io.FileInputStream;
import java.io.DataInputStream;

import org.eclipse.jdt.internal.core.util.Disassembler;
import org.eclipse.jdt.core.util.ClassFormatException;

/**
 * ClassDump : show a classfile dump the same way as Eclipse
 */
class ClassDump {

    public static void main(String[] args){

        System.out.println("Class dumper");
        if(args.length != 1){
            System.out.println("Usage : Disasm <file.class>");
            System.exit(1);
        }

        new ClassDump(args[0]);
    }

    public ClassDump(String classfile){

        byte[] classbuf = readClassBytes(classfile);

        System.out.println(String.format("Class size = %d bytes", classbuf.length));

        Disassembler dis = new Disassembler();
        try {
            System.out.print(dis.disassemble(classbuf, "\n", org.eclipse.jdt.internal.core.util.Disassembler.DETAILED));
        } catch(ClassFormatException cfe){
            cfe.printStackTrace();
        }
    }

    private byte[] readClassBytes(String classfile){
        byte[] buf;

        try{
            RandomAccessFile raf = new RandomAccessFile(classfile,"r");
            FileInputStream fis = new FileInputStream(raf.getFD());
            DataInputStream dis = new DataInputStream(fis);

            buf =  new byte[(int)raf.length()];
            dis.readFully(buf);

            dis.close();
            fis.close();
            raf.close();

        } catch (Exception ex){
            ex.printStackTrace();
            return new byte[0];
        }           

        return buf;

    }
}

On my local host, I compile with (you will probably need to change the jar name):

javac -cp \dev\tools\eclipse\plugins\org.eclipse.jdt.core_3.8.3.v20130121-145325.jar ClassDump.java

And the run has a bunch of dependencies with the Eclipse runtime jars (JDT core, osgi, equinox, ...), so I am cheating by using a wildcard to let java get all the needed jars:

java -cp .;\dev\tools\eclipse\plugins\* ClassDump SomeClass.class

It will print the same output as Eclipse clas file editor... HTH!

Seki
  • 11,135
  • 7
  • 46
  • 70
  • Thanks very much! BTW, I find a small mistake in your answer: the second command should be javap -c -p -s -v hello. The additional ".class" may cause javap can't find the file. – zzy Aug 03 '13 at 15:40
  • And the result of javap is a little different from the one showing in eclipse when opening it directly with eclipse. So do you know what package eclipse use to read the file? This answer mentioned a "javap-like" package: http://stackoverflow.com/questions/3062528/how-to-view-javas-byte-code – zzy Aug 03 '13 at 15:50
  • I have updated my answer to fix the `javap` call. I am invetigating how to call the eclipse built-in class decompiler, if possible. – Seki Aug 05 '13 at 12:56
  • I have managed to call eclipse internal class viewer by calling its classes from a minimal sample. I have updated my answer to show how. ^_^ – Seki Oct 23 '13 at 14:59
0

In your project directory, navigate to /bin , and there you will most likely have the .class-files that were automatically generated by Eclipse.

To see the java code for a compiled class file, you will have to use a java decompiler, such as this one.

The .class-file itself is compiled binary Java code, Eclipse automatically views the source for the class if any source for the class has been linked in your build path.

Simon Forsberg
  • 13,086
  • 10
  • 64
  • 108
  • Thanks! But how to read them? I just can't read them if I open them with notepad....... – zzy Aug 01 '13 at 20:24
  • BTW, I can open the class file directly and get its content. – zzy Aug 01 '13 at 20:27
  • Search the internet for a Hexadecimal editor and use it to read the hexadecimal values for each byte, if those will tell you anything. Notepad++ is an open source application that might help you. – Simon Forsberg Aug 01 '13 at 21:02
  • Following your guide, I've tried Notepad++ and UltraEdit. However, most of the content is still messy code and unreadable. The result I want is what eclipse shows when it opens class file directly. The eclipse result is totally readable. – zzy Aug 01 '13 at 21:13
  • Ah, what you want is a java decompiler. I will edit my answer – Simon Forsberg Aug 01 '13 at 21:14
  • en..... in fact what I what is not source code...... It is bytecode showing in eclipse like this: // Method descriptor #6 ()V // Stack: 1, Locals: 1 public test1(); 0 aload_0 [this] 1 invokespecial java.lang.Object() [8] 4 return Line numbers: [pc: 0, line: 3] Local variable table: [pc: 0, pc: 5] local: this index: 0 type: example.test1 – zzy Aug 01 '13 at 21:32
  • Well in that case you are not very good at asking a clear, understandable question. – Simon Forsberg Aug 01 '13 at 21:42
  • I'm sorry... Thx anyway~ – zzy Aug 01 '13 at 21:54
  • I'm not sure why you would want to see the bytecode, but if you ask a more clear question about that (including the bytecode example you wrote in your comment), then you will probably get more help. – Simon Forsberg Aug 01 '13 at 22:58