对于给定的 jar,我想找出该 jar 使用的所有类(尽可能)。由于我有很多 jar ,我想自动化这个过程。到目前为止我最好的想法是
- 反编译 jar(我没有这方面的经验,但应该有命令行工具)。
- 查找导入并解析它们。
但我希望其他人以前做过类似的事情并给我建议。
最佳答案
使用专门的工具可能是可靠地完成此操作的方法。
但是,一种非常笨拙的方法是获取所有 .class
的列表。 JAR 中的文件,将 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
改变/
发送至.
s 并删除 .class
扩展名,这样您最终会得到一个 Java 风格的类名列表。您可以更优雅地做到这一点,但它应该有效。
javap
调用将 jar 放在类路径上 -cp
,并通过了所有类(class)。 -v
使其输出大量信息,包括一些表示对类名称的引用的条目。 grep
确保我们只关注那些 sed
删除一些我们不感兴趣的额外信息。sort | uniq
确保我们不会多次打印任何类的名称。它确实需要更多sed
ding 标准化输出格式。
关于java - 获取 jar 的所有导入类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35892812/