java 如何确定应用程序中使用了哪些 JAR
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4222809/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to Determine which JARs are Used in an Application
提问by Aleks Felipe
An existing application has a ton of JAR files in its classpath. Someone must have added all JARs initially just to be sure. Some of the JARs were obviously not being used and we've already removed some of these unneeded JARs without causing any problems.
现有应用程序的类路径中有大量 JAR 文件。一定有人最初添加了所有 JAR 以确保。一些 JAR 显然没有被使用,我们已经删除了其中一些不需要的 JAR,而不会造成任何问题。
How does one determine which JARs are being used and which ones are unneeded (besides a trial and error method)?
如何确定哪些 JAR 正在被使用,哪些是不需要的(除了试错法)?
采纳答案by michael.kebe
Tattletaleis a great tool for this. It works on the bytecode, so it is possible, that some classes are use via reflection and will not come up in the report.
Tattletale是一个很好的工具。它适用于字节码,因此有可能某些类是通过反射使用的,并且不会出现在报告中。
Here(link no longer works) is an example report. As you can see, you just have the feature you are looking for "Unused JAR".
这里(链接不再有效)是一个示例报告。如您所见,您只拥有您正在寻找的功能“未使用的 JAR”。
回答by Grodriguez
Be aware that trial and error alone can be a problem, especially if the application loads classes dynamically (e.g. Class.forName
) as removing a JAR might not prevent the application from starting up and (apparently) work fine, but it may fail later if target classes are not found.
请注意,单独的反复试验可能是一个问题,特别是如果应用程序动态加载类(例如Class.forName
),因为删除 JAR 可能不会阻止应用程序启动并且(显然)工作正常,但如果目标类是未找到。
Also, there are many tools that can be used to analyze a Java application and find out dependencies (I have used Dependency Findermyself, although not exactly for this purpose), however note that most of them will also fail to find classes that are loaded dynamically as described above.
此外,有许多工具可用于分析 Java 应用程序并找出依赖项(我自己使用了Dependency Finder,虽然不完全是为此目的),但是请注意,其中大多数也无法找到已加载的类如上所述动态。
回答by ZoFreX
If any of them are loaded dynamically, it's possible that automated tools will miss them. I would reset the access times on the files, run the application for some time (and make sure to invoke as much functionality as possible), and see which files were accessed and which were not. You may need to repeat this on each platform your application needs to run on, just in case.
如果其中任何一个是动态加载的,自动化工具可能会错过它们。我会重置文件的访问时间,运行应用程序一段时间(并确保调用尽可能多的功能),然后查看哪些文件被访问,哪些没有。您可能需要在您的应用程序需要运行的每个平台上重复此操作,以防万一。
回答by J?rn Horstmann
I used the following shell script in a jboss portal project to get the list of jar files that are used in import statements. This will of yourse only work for direct dependencies, not for dynamically loaded or even when the fully qualified classname was used in the source. Furthermore, all jar files and their transitive dependencies are provided by the container so they are only needed to compile the code.
我在 jboss 门户项目中使用了以下 shell 脚本来获取导入语句中使用的 jar 文件列表。这仅适用于直接依赖项,不适用于动态加载甚至在源中使用完全限定的类名时。此外,所有 jar 文件及其传递依赖项都由容器提供,因此仅需要它们来编译代码。
The goal was to create a maven pom for the project and to find the files that needed to be deployed to our nexus repository manager. It might be useful as a starting point to list the files that are definitelyneeded, the remaining jar files would have to be checked in other ways. If the jar is also available in a maven repository you might look at its dependencies for example.
目标是为项目创建一个 maven pom 并找到需要部署到我们的 nexus 存储库管理器的文件。作为列出肯定需要的文件的起点可能很有用,其余的 jar 文件必须以其他方式检查。例如,如果 jar 在 Maven 存储库中也可用,您可以查看它的依赖项。
#!/bin/sh
JBOSS_HOME=/path/to/jboss/installation
JBOSS_LIB=$JBOSS_HOME/server/default/lib
JBOSS_DEPLOY=$JBOSS_HOME/server/default/deploy
SRC_DIR=src
for f in $JBOSS_LIB/*.jar $JBOSS_DEPLOY/jboss-portal.sar/lib/*.jar $JBOSS_DEPLOY/jboss-portal.sar/portal-cms.sar/lib/*.jar $JBOSS_DEPLOY/ejb3.deployer/*.jar
do
for c in `jar -tf $f | tr '/$' '..'`
do
#echo "^import ${c%.class};"
if `grep "^import ${c%.class};" -h -r $SRC_DIR -q`
then
echo $f $c
fi
done
done