D:\jd-cli-dist>jd-cli.bat -od test javafunction.jar
13:20:52.850 INFO com.github.kwart.jd.cli.Main - Decompiling javafunction.jar
13:20:52.854 INFO com.github.kwart.jd.output.DirOutput - Directory output will be initialized for path test
13:20:52.930 INFO com.github.kwart.jd.output.DirOutput - Finished with 1 class file(s) and 1 resource file(s) written.
D:\jd-cli-dist\test>type com\example\Handler.java
package com.example;
import com.google.gson.JsonObject;
public class Handler {
public JsonObject handleRequest(JsonObject request) {
JsonObject response = new JsonObject();
response.addProperty("request", request.toString());
response.addProperty("response", "Hello Serverless World!");
return response;
}
}
(1) Loader 인터페이스 구현
Loader loader = new Loader() {
@Override
public byte[] load(String internalName) throws LoaderException {
InputStream is = this.getClass().getResourceAsStream("/" + internalName + ".class");
if (is == null) {
return null;
} else {
try (InputStream in=is; ByteArrayOutputStream out=new ByteArrayOutputStream()) {
byte[] buffer = new byte[1024];
int read = in.read(buffer);
while (read > 0) {
out.write(buffer, 0, read);
read = in.read(buffer);
}
return out.toByteArray();
} catch (IOException e) {
throw new LoaderException(e);
}
}
}
@Override
public boolean canLoad(String internalName) {
return this.getClass().getResource("/" + internalName + ".class") != null;
}
};
(2) Printer 인터페이스 구현
Printer printer = new Printer() {
protected static final String TAB = " ";
protected static final String NEWLINE = "\n";
protected int indentationCount = 0;
protected StringBuilder sb = new StringBuilder();
@Override public String toString() { return sb.toString(); }
@Override public void start(int maxLineNumber, int majorVersion, int minorVersion) {}
@Override public void end() {}
@Override public void printText(String text) { sb.append(text); }
@Override public void printNumericConstant(String constant) { sb.append(constant); }
@Override public void printStringConstant(String constant, String ownerInternalName) { sb.append(constant); }
@Override public void printKeyword(String keyword) { sb.append(keyword); }
@Override public void printDeclaration(int type, String internalTypeName, String name, String descriptor) { sb.append(name); }
@Override public void printReference(int type, String internalTypeName, String name, String descriptor, String ownerInternalName) { sb.append(name); }
@Override public void indent() { this.indentationCount++; }
@Override public void unindent() { this.indentationCount--; }
@Override public void startLine(int lineNumber) { for (int i=0; i<indentationCount; i++) sb.append(TAB); }
@Override public void endLine() { sb.append(NEWLINE); }
@Override public void extraLine(int count) { while (count-- > 0) sb.append(NEWLINE); }
@Override public void startMarker(int type) {}
@Override public void endMarker(int type) {}
};
(3) "decompile(loader, Printer, InternalTypeName);" 메소드를 호출
ClassFileToJavaSourceDecompiler decompiler = new ClassFileToJavaSourceDecompiler();
decompiler.decompile(loader, printer, "path/to/YourClass");
String source = printer.toString();
JD-GUI | JD-CLI | JD-CORE | |
---|---|---|---|
라이센스 | GPL-3.0 | GPL-3.0 | GPL-3.0 |
공식 여부 | 공식 | 비공식 | 공식 |
지원 범위 | Java 1.1.8 ~ Java 12.0 | Java 1.1.8 ~ Java 12.0 | Java 1.1.8 ~ Java 12.0 |
장점 | 다양한 OS 지원, GUI 지원 | 현재 요건에 맞는 서비스 개발 가능 | 현재 요건에 맞는 서비스 개발 가능 |
단점 | CLI 제공 X | 비공식 툴, OS Command 기반의 호출 필요 | 별도 디컴파일러에 대한 별도 개발 공수 |