想作一個在線java反編譯工具,找了http://jd.benow.ca/ http://varaneckas.com/jad/ 這兩個工具。java
前一個工具比較好,可是jd-core不沒有提供下載。詳見 http://zhouliang.pro/2010/06/26/jad/ node
搜索中發現了這個項目 https://github.com/nviennot/jd-core-java/ linux
JD-Core-java is a thin-wrapper for the Java Decompiler.git
This is hack around the IntelliJ IDE plugin. It fakes the interfaces of the IDE, and provides access to JD-Core.github
Since the Author of JD-Core is not willing to provide a library, as seen on this thread, and we all want to batch decompilation, this is pretty much our only option.app
I hope this will motivate the author to release a proper library.eclipse
這個是抽取IntelliJ IDE jd plugin的插件中的jd-core來實現的,可是如今只有linux版本的。ide
受此啓示,我下載eclipse的jd插件,應該也是包含的。果不其然,是包含的。工具
可是,抽取代碼的發現了一些問題,就是反編譯不徹底。不知道是哪裏出了問題。ui
改寫了下面的代碼:
package jd.ide.eclipse.editors; public class JDSourceMapper { private final static String JAVA_CLASS_SUFFIX = ".class"; private final static String JAVA_SOURCE_SUFFIX = ".java"; private final static int JAVA_SOURCE_SUFFIX_LENGTH = 5; private final static String JAR_SUFFIX = ".jar"; private final static String ZIP_SUFFIX = ".zip"; private static boolean loaded = true; static { System.load("d://jd-eclipse.dll"); } public static void main(String[] args) { JDSourceMapper jd = new JDSourceMapper(); String s = jd.decompile("d:/antlr-2.7.7.jar", "antlr/ActionElement.class"); System.out.println(s); } public native String decompile(String basePath, String classPath); }
可是反編譯出來的結構是這樣的:
package antlr; class ActionElement extends AlternativeElement { protected String actionText; protected boolean isSemPred = false; // ERROR // public ActionElement(Grammar paramGrammar, Token paramToken) { // Byte code: // 0: aload_0 // 1: aload_1 // 2: invokespecial 1 antlr/AlternativeElement:<init> (Lantlr/Grammar;)V // 5: aload_0 // 6: iconst_0 // 7: putfield 2 antlr/ActionElement:isSemPred Z // 10: aload_0 // 11: aload_2 // 12: invokevirtual 3 antlr/Token:getText ()Ljava/lang/String; // 15: putfield 4 antlr/ActionElement:actionText Ljava/lang/String; // 18: aload_0 // 19: aload_2 // 20: invokevirtual 5 antlr/Token:getLine ()I // 23: putfield 6 antlr/ActionElement:line I // 26: aload_0 // 27: aload_2 // 28: invokevirtual 7 antlr/Token:getColumn ()I // 31: putfield 8 antlr/ActionElement:column I // 34: return } // ERROR // public void generate() { // Byte code: // 0: aload_0 // 1: getfield 9 antlr/ActionElement:grammar Lantlr/Grammar; // 4: getfield 10 antlr/Grammar:generator Lantlr/CodeGenerator; // 7: aload_0 // 8: invokevirtual 11 antlr/CodeGenerator:gen (Lantlr/ActionElement;)V // 11: return } // ERROR // public Lookahead look(int paramInt) { // Byte code: // 0: aload_0 // 1: getfield 9 antlr/ActionElement:grammar Lantlr/Grammar; // 4: getfield 12 antlr/Grammar:theLLkAnalyzer Lantlr/LLkGrammarAnalyzer; // 7: iload_1 // 8: aload_0 // 9: invokeinterface 13 3 0 // 14: areturn } // ERROR // public String toString() { // Byte code: // 0: new 14 java/lang/StringBuffer // 3: dup // 4: invokespecial 15 java/lang/StringBuffer:<init> ()V // 7: ldc 16 // 9: invokevirtual 17 java/lang/StringBuffer:append (Ljava/lang/String;)Ljava/lang/StringBuffer; // 12: aload_0 // 13: getfield 4 antlr/ActionElement:actionText Ljava/lang/String; // 16: invokevirtual 17 java/lang/StringBuffer:append (Ljava/lang/String;)Ljava/lang/StringBuffer; // 19: aload_0 // 20: getfield 2 antlr/ActionElement:isSemPred Z // 23: ifeq +8 -> 31 // 26: ldc 18 // 28: goto +5 -> 33 // 31: ldc 19 // 33: invokevirtual 17 java/lang/StringBuffer:append (Ljava/lang/String;)Ljava/lang/StringBuffer; // 36: invokevirtual 20 java/lang/StringBuffer:toString ()Ljava/lang/String; // 39: areturn } }
能夠看出方法沒有反編譯出來,可是在jd-gui中出來的結果是好的。不知道哪裏出了問題。