【发布时间】:2017-08-25 19:02:13
【问题描述】:
现有应用程序的类路径中有大量 JAR 文件。为了确定,必须有人最初添加了所有 JAR。一些 JAR 显然没有被使用,我们已经删除了其中一些不需要的 JAR,没有造成任何问题。
如何确定哪些 JAR 正在使用,哪些是不需要的(除了试错法)?
【问题讨论】:
现有应用程序的类路径中有大量 JAR 文件。为了确定,必须有人最初添加了所有 JAR。一些 JAR 显然没有被使用,我们已经删除了其中一些不需要的 JAR,没有造成任何问题。
如何确定哪些 JAR 正在使用,哪些是不需要的(除了试错法)?
【问题讨论】:
Tattletale 是一个很好的工具。它适用于字节码,因此有可能某些类是通过反射使用的,不会出现在报告中。
Here(链接不再有效)是一个示例报告。如您所见,您只需要“Unused JAR”的功能。
【讨论】:
请注意,单独试验和错误可能是一个问题,特别是如果应用程序动态加载类(例如Class.forName),因为删除 JAR 可能不会阻止应用程序启动并且(显然)工作正常,但它可能如果找不到目标类,则稍后会失败。
另外,有很多工具可以用来分析 Java 应用程序并找出依赖关系(我自己使用过Dependency Finder,虽然不完全是为了这个目的),但是请注意,它们中的大多数也无法找到如上所述动态加载的类。
【讨论】:
如果它们中的任何一个是动态加载的,那么自动化工具可能会错过它们。我会重置文件的访问时间,运行应用程序一段时间(并确保调用尽可能多的功能),然后查看哪些文件被访问,哪些文件未被访问。您可能需要在应用程序需要运行的每个平台上重复此操作,以防万一。
【讨论】:
我在一个 jboss 门户项目中使用了以下 shell 脚本来获取导入语句中使用的 jar 文件列表。这仅适用于直接依赖项,不适用于动态加载,甚至在源代码中使用了完全限定的类名时。此外,所有 jar 文件及其传递依赖项均由容器提供,因此仅在编译代码时需要它们。
我们的目标是为项目创建一个 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
【讨论】: