获取一个 jar 的所有导入 类
Getting all imported classes for a jar
对于给定的jar,我想找出这个jar 使用的所有类(尽可能)。因为我有很多罐子,所以我想自动化这个过程。到目前为止我最好的想法是
- 反编译jar(我没有这方面的经验,但应该有命令行工具)。
- 查找导入并解析它们。
但我希望之前有人做过类似的事情并给我建议。
一种简单的方法是尝试在不添加该 jar 的情况下编译您的代码。
尝试编译并查看编译器错误是最快的方法。
但请记住,class 也可以使用反射(例如通过 spring 配置文件)在运行时加载,并且在没有 jar 的情况下编译代码不会通知您运行时的潜在错误.
使用专门的工具可能是可靠地做到这一点的方法。
但是,一种非常笨拙的方法是获取 JAR 中所有 .class
文件的列表,将 JAR 放在 class 路径上并使用 javap
以获取对其他 classes:
的引用
#!/usr/bin/env bash
javap -cp -v \
`zipinfo -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 '*.class'
将打印出 </code> 中所有 <code>.class
文件的名称,这是显示的脚本的参数。 sed
s 将 /
s 更改为 .
s 并删除 .class
扩展名,这样你就得到了一个 Java 风格的列表 class 名字。您可以更优雅地执行此操作,但它应该可以工作。
javap
调用将 jar 放在 -cp
的 class 路径上,并传递所有 classes。 -v
使它输出大量信息,包括一些代表对 classes 名称的引用的条目。 grep
确保我们只查看那些,sed
删除了一些我们不感兴趣的额外信息。sort | uniq
确保我们不打印任何 [=45] 的名称=]不止一次。它确实需要更多 sed
来标准化输出格式。
对于给定的jar,我想找出这个jar 使用的所有类(尽可能)。因为我有很多罐子,所以我想自动化这个过程。到目前为止我最好的想法是
- 反编译jar(我没有这方面的经验,但应该有命令行工具)。
- 查找导入并解析它们。
但我希望之前有人做过类似的事情并给我建议。
一种简单的方法是尝试在不添加该 jar 的情况下编译您的代码。
尝试编译并查看编译器错误是最快的方法。
但请记住,class 也可以使用反射(例如通过 spring 配置文件)在运行时加载,并且在没有 jar 的情况下编译代码不会通知您运行时的潜在错误.
使用专门的工具可能是可靠地做到这一点的方法。
但是,一种非常笨拙的方法是获取 JAR 中所有 .class
文件的列表,将 JAR 放在 class 路径上并使用 javap
以获取对其他 classes:
#!/usr/bin/env bash
javap -cp -v \
`zipinfo -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 '*.class'
将打印出 </code> 中所有 <code>.class
文件的名称,这是显示的脚本的参数。 sed
s 将 /
s 更改为 .
s 并删除 .class
扩展名,这样你就得到了一个 Java 风格的列表 class 名字。您可以更优雅地执行此操作,但它应该可以工作。
javap
调用将 jar 放在 -cp
的 class 路径上,并传递所有 classes。 -v
使它输出大量信息,包括一些代表对 classes 名称的引用的条目。 grep
确保我们只查看那些,sed
删除了一些我们不感兴趣的额外信息。sort | uniq
确保我们不打印任何 [=45] 的名称=]不止一次。它确实需要更多 sed
来标准化输出格式。