找出实际加载了哪些Java类并减少jar

时间:2018-11-06 08:22:20

标签: java maven

是否有一种方法可以自动找出实际加载了哪些Java类(尽可能在编译时或在应用程序运行时),并从JAR中排除所有其他类以进行创建较小的JAR?在实践中这真的有意义吗?

我正在谈论应用程序JAR的应用程序类。通常,应用程序中有很多库,而应用程序很少需要这些库的所有功能。因此,我怀疑这将使应用程序小得多。从理论上讲,这可以通过例如Java代理来完成,该Java代理记录应用程序的一次或多次运行(甚至仅通过java -verbose:class)读取哪些类和资源,以及抛出所有其他类的maven插件。从具有依赖项的jar中获取。已经有这样的东西了吗?

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

3 个答案:

答案 0 :(得分:1)

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

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

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

答案 1 :(得分:0)

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

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

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

答案 2 :(得分:0)

全球战略。

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

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

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

我已经完成了第一部分和第二部分,所以我可以为您提供帮助。


1)找出所有已加载的类。您需要100%的代码覆盖率(我不是在谈论测试,而是在生产)。因此,请运行所有可能的方案,以便将加载和记录您的应用程序所需的所有类。

要记录加载的类,请尝试几种方法。 Reflection–verbose:class flag,您还可以了解Java代理。它允许在运行时修改方法。 This is an example of some java agent codeanother java agent example

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

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

您还可以使用工具(同样,您是程序员,因此请编写程序),该工具检查代码是否与类相关。如果它们用于编译,则您不想删除它们。当我还是学生的时候,我写了代码alanyzer,它为类依赖关系构建了一个面向对象的图。

正如@Gokul Nath KP所指出的,我之前曾这样做。我手动更改gradle和maven依赖项,一一删除,然后进行全面回归测试。我花了一个星期的时间(与数百个开发人员创建的现代企业系统相比,我们的应用程序很小)。

所以,要有创造力,一旦成功,您的项目将被数以百万计的人使用!

相关问题