获取jar的所有导入类

时间:2016-03-09 13:22:35

标签: java jar decompiling

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

  1. 反编译jar(我没有经验,但应该有命令行工具)。
  2. 查找导入并解析它们。
  3. 但我希望其他人之前做过类似的事情并就此提出建议。

2 个答案:

答案 0 :(得分:2)

使用专用工具可能是可靠地实现这一目标的方法。

然而,这样做的一个非常简洁的方法是获取JAR中所有.class文件的列表,将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

guava-19.0.jar上运行此内容会this

"[[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"

您需要更多的输出格式,并且正如其他人所指出的那样,它不会使用任何反射。

这是如何运作的:

zipinfo -1 $1 '*.class'将打印出.class中所有$1个文件的名称,这是所显示脚本的参数。 sed/更改为.并删除.class扩展名,以便最终得到一个Java样式的类名列表。你可以更优雅地做到这一点,但它应该有用。

javap调用将jar放在带有-cp的类路径上,并传递所有类。 -v使其输出大量信息,包括一些表示类名称引用的条目。 grep确保我们只查看这些内容,sed删除了一些我们不感兴趣的额外信息。sort | uniq确保我们不打印任何类的名称不止一次。它确实需要更多sed ding来标准化输出格式。

答案 1 :(得分:0)

一种简单的方法是尝试编译代码而不添加该jar。

尝试编译并查看编译器错误是最快的方法。

但请记住,一个类也可以使用反射加载运行时(例如通过spring配置文件),并且在没有jar的情况下编译代码不会在运行时通知您潜在的错误。