7

有没有办法自动找出实际加载了哪些 Java 类(在编译时,尽可能地,或者在应用程序的运行时),并从 JAR 中丢弃所有其他类以创建更小的 JAR ? 这在实践中真的有意义吗?

我说的是应用程序 JAR 的应用程序类。通常一个应用程序中有很多库,一个应用程序很少需要这些库的所有功能。所以我怀疑这会产生一个相当小的应用程序。理论上,这可以通过一个 Java 代理来完成,该代理记录哪些类和资源被应用程序的一次或多次运行(甚至只是 java -verbose:class)读取,以及一个抛出所有其他类的 maven 插件从带有依赖项的 jar 中。已经有类似的东西了吗?

澄清:我不是在谈论未使用的依赖项(根本不使用的 JAR),而是关于删除每个包含的 JAR 的未使用部分。

4

3 回答 3

1

好吧,Maven Shade 插件在minimizeJar为您的应用程序创建 Uber-JAR 时有一个选项:

https://maven.apache.org/plugins/maven-shade-plugin/

但是,正如其他人已经指出的那样,这是非常危险的,因为它经常无法检测通过反射或其他动态引用完成的类访问。

于 2018-11-06T09:28:33.950 回答
0

全球战略。

1) 查找在运行时加载的所有类。

2) 类路径中所有可用类的列表。

3)通过创建仅包含您需要的类的 jar 副本来减少您的类路径。

我已经完成了 1 和 2 部分,所以我可以帮助你。


1)找出所有加载的类。您需要 100% 的代码覆盖率(我不是在谈论测试,而是在谈论生产)。所以运行所有可能的场景,这样你的应用程序需要的所有类都将被加载和记录。

要记录加载的类,请尝试几种方法。Reflection , --verbose:class flag , 你也可以了解一下java agent。它允许在运行时修改方法。这是一些 java 代理代码另一个 java 代理示例的示例

2)要查找jar中所有可用的类,您可以编写一个程序。您需要知道放置应用程序 jar 的所有位置。循环抛出这些罐子(您可以使用ZipFile),循环访问ZipFileEntry条目,并收集所有类。

3) 之后编写一个脚本或程序来重新组装您的应用程序。例如,现在您可以为每个库创建一个新的 jar 文件,并在其中放置只需要的类。

你也可以使用一个工具(同样,你是一个程序员,所以写一个程序),它检查代码的类依赖性。如果类用于编译,您不想删除它们。当我还是学生的时候,我编写了代码 alanyzer,它为类依赖关系构建了一个有向图。

正如@Gokul Nath KP 所指出的,我以前做过。我手动更改 gradle 和 maven 依赖项,一一删除,然后进行完整的回归测试。我花了一周的时间(与数百名开发人员创建的现代世界企业系统相比,我们的应用程序很小)。

所以,要有创意,如果成功,你的项目将被数百万人使用!

于 2018-11-06T09:50:08.557 回答
0

自动化可能不是一个好方法,因为应用程序可以使用反射来初始化对象,或者一个 JAR 依赖于另一个 JAR。

我能想到的唯一方法是逐个删除每个 JAR 并检查应用程序是否按预期运行。然后再次在这种方法中,必须测试应用程序的所有模块,因为一个模块可以在没有特定依赖关系的情况下工作,而其他模块则不能。

更好的解决方案是在开发时小心。应用程序开发人员在他/她的代码完成后添加依赖项和删除不需要的依赖项时必须小心。

于 2018-11-06T08:45:13.073 回答