[英]Getting all imported classes for a jar
For a given jar, I want to find out all classes (as far as possible) that are used by this jar. 对于给定的jar,我想找出该jar使用的所有类(尽可能)。 Since I have a lot of jars, I want to automate this process.
由于我有很多罐子,因此我想使这一过程自动化。 My best idea so far is to
到目前为止,我最好的主意是
But I hope that someone else has done something like this before and give me advice on this. 但是我希望其他人以前做过这样的事情,并就此给我建议。
Using a specialised tool is probably the way to do this reliably. 使用专用工具可能是可靠地实现此目的的方法。
However, one really janky way of doing this would be to grab a list of all the .class
files in your JAR, put the JAR on the classpath and use javap
to get references to other classes: 但是,这样做的一种真正麻烦的方法是获取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
Running this on guava-19.0.jar
gives this : 在
guava-19.0.jar
上运行此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"
You'll need more output formatting, and, as others have pointed out, it won't pick up any use of reflection. 您将需要更多的输出格式,并且正如其他人指出的那样,它将不会使用任何反射。
How this works: 工作原理:
zipinfo -1 $1 '*.class'
will print out the names of all .class
files in $1
, which is the argument to the script shown. zipinfo -1 $1 '*.class'
将打印$1
中所有.class
文件的名称,这是所示脚本的参数。 The sed
s change /
s to .
该
sed
更迭/
s到.
s and remove the .class
extension, so that you end up with a list of Java-style class names. 并删除
.class
扩展名,以便最终获得Java样式的类名列表。 You could do this more elegantly, but it should work. 您可以更优雅地执行此操作,但它应该可以工作。
The javap
invocation puts the jar on the classpath with -cp
, and passes all the classes. javap
调用使用-cp
将jar放在类路径中,并传递所有类。 -v
makes it output a lot of information, including some entries which represent references to names of classes. -v
使它输出大量信息,包括一些表示对类名称的引用的条目。 The grep
ensures we're only looking at those, the sed
removes some extra information we're not interested in. sort | uniq
在
grep
保证我们只是看着那些中, sed
删除我们不感兴趣,一些额外的信息。 sort | uniq
sort | uniq
ensures we're not printing the name of any class more than once. sort | uniq
确保我们不会多次打印任何类的名称。 It does need a bit more sed
ding to standardize an output format. 它需要更多的
sed
丁标准化的输出格式。
A simple way is to try to compile your code without adding that jar. 一种简单的方法是尝试在不添加该jar的情况下编译代码。
Try to compile and looking at the compiler errors is the fastest way to do that. 尝试编译并查看编译器错误是最快的方法。
But remember that a class can be loaded also a runtime using reflection (for example via spring configuration files) and compiling the code without the jar will not inform you about potential errors at runtime. 但是请记住,也可以使用反射(例如,通过spring配置文件)在运行时加载类,并且在不使用jar的情况下编译代码不会通知您运行时的潜在错误。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.