获取 jar 的所有导入类

JF *_*ier 1 java decompiling jar

对于给定的 jar,我想找出该 jar 使用的所有类(尽可能)。由于我有很多罐子,我想自动化这个过程。到目前为止我最好的想法是

  1. 反编译jar(我没有这方面的经验,但应该有命令行工具)。
  2. 查找导入并解析它们。

但我希望其他人以前做过类似的事情并给我建议。

Vla*_*lad 5

使用专门的工具可能是可靠地完成此操作的方法。

然而,一种非常简单的方法是获取.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努力来标准化输出格式。