JF *_*ier 1 java decompiling jar
对于给定的 jar,我想找出该 jar 使用的所有类(尽可能)。由于我有很多罐子,我想自动化这个过程。到目前为止我最好的想法是
但我希望其他人以前做过类似的事情并给我建议。
使用专门的工具可能是可靠地完成此操作的方法。
然而,一种非常简单的方法是获取.classJAR 中所有文件的列表,将 JAR 放在类路径上并用于javap获取对其他类的引用:
#!/usr/bin/env bash
javap -cp $1 -v \
`zipinfo -1 $1 '*.class' | sed 's:/:.:g' | sed 's:\.class$::'` | \
grep ' = Class' | sed 's:.*// ::' | sort | uniq
Run Code Online (Sandbox Code Playgroud)
运行此命令guava-19.0.jar会给出以下结果:
"[[B"
"[B"
"[[C"
"[C"
com/google/common/annotations/Beta
com/google/common/annotations/GwtCompatible
com/google/common/annotations/GwtIncompatible
com/google/common/annotations/VisibleForTesting
com/google/common/base/Absent
com/google/common/base/AbstractIterator
...............................................................
"[Lcom/google/common/util/concurrent/MoreExecutors$DirectExecutor;"
"[Lcom/google/common/util/concurrent/Service$State;"
"[Lcom/google/thirdparty/publicsuffix/PublicSuffixType;"
"[Ljava/io/File;"
"[[Ljava/lang/annotation/Annotation;"
"[Ljava/lang/annotation/Annotation;"
"[Ljava/lang/Class;"
"[Ljava/lang/Comparable;"
"[Ljava/lang/Enum;"
"[[Ljava/lang/Object;"
"[Ljava/lang/Object;"
"[Ljava/lang/reflect/Field;"
"[Ljava/lang/reflect/Method;"
"[Ljava/lang/reflect/Type;"
"[Ljava/lang/reflect/TypeVariable;"
"[Ljava/lang/StackTraceElement;"
"[Ljava/lang/String;"
"[Ljava/net/URL;"
"[Ljava/util/Iterator;"
"[Ljava/util/Map$Entry;"
"[[S"
"[S"
sun/misc/Unsafe
"[[Z"
"[Z"
Run Code Online (Sandbox Code Playgroud)
您将需要更多的输出格式,并且正如其他人指出的那样,它不会使用任何反射。
这是如何运作的:
zipinfo -1 $1 '*.class'.class将打印出中所有文件的名称$1,这是所示脚本的参数。s将 ssed更改/为.s 并删除.class扩展名,这样您最终会得到 Java 样式的类名列表。你可以更优雅地做到这一点,但它应该有效。
该javap调用将 jar 放在类路径上-cp,并传递所有类。-v使其输出大量信息,包括一些表示对类名称的引用的条目。确保grep我们只查看这些信息,sed删除一些我们不感兴趣的额外信息。sort | uniq确保我们不会多次打印任何类的名称。它确实需要更多的sed努力来标准化输出格式。