mirror of
https://github.com/alibaba/arthas.git
synced 2024-04-21 10:21:39 +00:00
jad command support -d/--directory option (#2646)
This commit is contained in:
+11
-6
@@ -52,18 +52,23 @@ class ClassDumpTransformer implements ClassFileTransformer {
|
||||
return dumpResult;
|
||||
}
|
||||
|
||||
private void dumpClassIfNecessary(Class<?> clazz, byte[] data) {
|
||||
String className = clazz.getName();
|
||||
ClassLoader classLoader = clazz.getClassLoader();
|
||||
public File dumpDir() {
|
||||
String classDumpDir = "classdump";
|
||||
|
||||
// 创建类所在的包路径
|
||||
File dumpDir = null;
|
||||
final File dumpDir;
|
||||
if (directory != null) {
|
||||
dumpDir = directory;
|
||||
} else {
|
||||
dumpDir = new File(arthasLogHome, classDumpDir);
|
||||
}
|
||||
return dumpDir;
|
||||
}
|
||||
|
||||
private void dumpClassIfNecessary(Class<?> clazz, byte[] data) {
|
||||
String className = clazz.getName();
|
||||
ClassLoader classLoader = clazz.getClassLoader();
|
||||
|
||||
// 创建类所在的包路径
|
||||
File dumpDir = dumpDir();
|
||||
if (!dumpDir.mkdirs() && !dumpDir.exists()) {
|
||||
logger.warn("create dump directory:{} failed.", dumpDir.getAbsolutePath());
|
||||
return;
|
||||
|
||||
@@ -47,6 +47,7 @@ import java.util.regex.Pattern;
|
||||
@Description(Constants.EXAMPLE +
|
||||
" jad java.lang.String\n" +
|
||||
" jad java.lang.String toString\n" +
|
||||
" jad java.lang.String -d /tmp/jad/dump\n" +
|
||||
" jad --source-only java.lang.String\n" +
|
||||
" jad -c 39eb305e org/apache/log4j/Logger\n" +
|
||||
" jad -c 39eb305e -E org\\\\.apache\\\\.*\\\\.StringUtils\n" +
|
||||
@@ -62,6 +63,7 @@ public class JadCommand extends AnnotatedCommand {
|
||||
private boolean isRegEx = false;
|
||||
private boolean hideUnicode = false;
|
||||
private boolean lineNumber;
|
||||
private String directory;
|
||||
|
||||
/**
|
||||
* jad output source code only
|
||||
@@ -118,6 +120,12 @@ public class JadCommand extends AnnotatedCommand {
|
||||
this.lineNumber = lineNumber;
|
||||
}
|
||||
|
||||
@Option(shortName = "d", longName = "directory")
|
||||
@Description("Sets the destination directory for dummped class files required by cfr decompiler")
|
||||
public void setDirectory(String directory) {
|
||||
this.directory = directory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void process(CommandProcess process) {
|
||||
RowAffect affect = new RowAffect();
|
||||
@@ -173,10 +181,19 @@ public class JadCommand extends AnnotatedCommand {
|
||||
allClasses.add(c);
|
||||
|
||||
try {
|
||||
ClassDumpTransformer transformer = new ClassDumpTransformer(allClasses);
|
||||
final ClassDumpTransformer transformer;
|
||||
if (directory == null) {
|
||||
transformer = new ClassDumpTransformer(allClasses);
|
||||
} else {
|
||||
transformer = new ClassDumpTransformer(allClasses, new File(directory));
|
||||
}
|
||||
InstrumentationUtils.retransformClasses(inst, transformer, allClasses);
|
||||
|
||||
Map<Class<?>, File> classFiles = transformer.getDumpResult();
|
||||
if (classFiles == null || classFiles.isEmpty()) {
|
||||
return ExitStatus.failure(-1, "jad: fail to dump class file for decompiler, make sure you have write permission of the directory \"" + transformer.dumpDir() +
|
||||
"\" or try with \"-d/--directory\" to specify the directory of dump files");
|
||||
}
|
||||
File classFile = classFiles.get(c);
|
||||
|
||||
Pair<String,NavigableMap<Integer,Integer>> decompileResult = Decompiler.decompileWithMappings(classFile.getAbsolutePath(), methodName, hideUnicode, lineNumber);
|
||||
|
||||
@@ -176,3 +176,11 @@ Affect(row-cnt:1) cost in 190 ms.
|
||||
对于只有唯一实例的 ClassLoader 还可以通过`--classLoaderClass`指定 class name,使用起来更加方便:
|
||||
|
||||
`--classLoaderClass` 的值是 ClassLoader 的类名,只有匹配到唯一的 ClassLoader 实例时才能工作,目的是方便输入通用命令,而`-c <hashcode>`是动态变化的。
|
||||
|
||||
### 反编译时指定dump class文件目录
|
||||
|
||||
`jad`反编译需要将class dump到文件,默认会dump到logback.xml中配置的log目录下,使用`-d/--directory`可以将文件dump到指定目录。
|
||||
|
||||
```java
|
||||
$ jad demo.MathGame -d /tmp/jad/dump
|
||||
```
|
||||
@@ -176,3 +176,11 @@ Affect(row-cnt:1) cost in 190 ms.
|
||||
For classloader with only one instance, it can be specified by `--classLoaderClass` using class name, which is more convenient to use.
|
||||
|
||||
The value of `--classloaderclass` is the class name of classloader. It can only work when it matches a unique classloader instance. The purpose is to facilitate the input of general commands. However, `-c <hashcode>` is dynamic.
|
||||
|
||||
### Decompile with specified directory for dumpping class
|
||||
|
||||
Decompile class with `jad` need to dump corresponding classes into files. The default directory for dumpping classes is the directory of log file specified in logback.xml, we can use `-d/--directory` to specify the directory for dummping class.
|
||||
|
||||
```java
|
||||
$ jad demo.MathGame -d /tmp/jad/dump
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user