Java – 如何减小第三方jar的大小以减小应用程序的大小

我正在开发一个java Web应用程序 ,其中包括一个applet 。 该applet依赖于两个jar文件:

  • JFreeChart (用于在客户端绘制图形) – 1.7 mb(jar文件的大小)
  • MySqlJdbcConnector(用于存储在客户端捕获的数据到远程数据库) – .7 mb(jar文件的大小)

现在,问题是上面两个jar文件的大小。 我的applet jar (myApplet.jar)的总大小是2.5 MB ,其中2.4 MB是由于上面两个jar文件。

我没有使用那些jar文件中的所有类。 具体来说,对于jfreechart ,我使用的是来自该库的极少数类。

============================== 问题 =================== ===================

Q1。 为了创建myApplet.jar文件,我所做的是解压缩了两个jar文件(jfreechart和mySQLJdbcConnector),然后用我的applet代码的源代码打包解压缩版本的jar文件,以创建一个jar文件( 即myApplet.jar)。 这是用你的applet代码打包第三方jar文件的正确方法吗? 有什么方法可以优化这个吗?

Q2。 我试图找到我在我的应用程序中使用的jfreechart库类的依赖关系,以便只在myApplet.jar中打包这些依赖项。 为此,我使用DependencyAnalyzer来查找所有类的依赖关系。 但后来我发现很难手动执行,因为每个类(我在我的应用程序中使用的jfreechart类)都有很多依赖项,而且我使用了15个类的jfreechart,所以对每个类执行此操作将非常困难。 那有什么建议吗?

Q3。 这种情况是非常普遍的开发人员遇到或我遗失的东西,因为我必须这样做?

A1:

您可以创建ant脚本或使用Eclipse或任何其他IDE自动打包applet。 但你的方式也是正确的

A2:

我不会手动做这些事情。 寻找传递依赖性非常复杂。 也许darioo的答案是一个更好的方法来做到这一点。

A3:

这确实非常普遍。 一些提示:

您始终可以在没有调试信息的情况下重新构建这些第三方库。 这应该会略微减少这些库的大小。

另一方面,也许您不应该从applet直接连接到数据库。 您可以创建一个RMI接口(或类似的东西)来将SQL和结果数据传输到实际执行SQL的应用程序服务器。 如果您不在安全的Intranet中运行它,这对您的applet来说是一个重要的安全方面。

我建议尝试ProGuard 。 您可以排除未使用的部分jar文件。

是的,您可以通过创建仅包含您的applet所需的类的JAR来节省空间。 (我已经看到这称为超级JAR。)

这样做有各种工具; 例如ProGuard,Zelix ClassMaster,一个名字我遗忘的Maven插件,依此类推。

但是有一些问题,至少在一般情况下是这样:

  • 如果您的代码使用动态加载(例如,通过调用Class.forName(className) ),这些工具通常无法检测依赖项。 因此,为了避免动态加载的类被排除在最终的JAR之外,您需要告诉工具应用程序可能以这种方式显式加载的所有类的名称。

  • 您需要查看第三方库的许可证。 IIRC,某些许可证要求您以允许人们替换库的不同版本的方式将库包含在您的分布式工件中。 有人可能会说,超级JAR让这很难做到,因此可能会有问题。

JFreeChart是LGPL,LGPL是具有上述要求的许可证。 然而,MySQL是GPL,它胜过LGPL,这意味着你的applet必须是GPL’…如果你分发它。


最后,如果您想最小化applet JAR的大小,则不应将您的源代码包含在JAR中。 源代码应该在单独的JAR(或ZIP,TAR或其他)文件中。