对于给定的jar,我想找出这个jar使用的所有类(尽可能)。由于我有很多罐子,我想自动化这个过程。到目前为止,我最好的想法是
但我希望其他人之前做过类似的事情并就此提出建议。
答案 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的情况下编译代码不会在运行时通知您潜在的错误。