生成仅包含使用的类的最小化 jar
Posted
技术标签:
【中文标题】生成仅包含使用的类的最小化 jar【英文标题】:Generate minimized jar with only used classes 【发布时间】:2012-03-20 01:50:48 【问题描述】:我需要创建用于 android 的最小 jar 实用程序库。我正在使用 apache 公共库中的一些方法(例如IOUtils
、StringUtils
)。然而,每一次这样的使用都会让我导入整个库(commons-lang
、commons-io
等),这在 Tomcat 下是绝对可以接受的(war
无论如何都是 mamoot 大小的),但对于 Android 项目绝对不能接受。
所以,我的目标是将所有使用过的类从依赖项打包到一个 jar 中——但只有那些需要的类。我记得曾经接触过完成该任务的 maven 插件,不幸的是我不记得它的名字,也无法通过 Google 找到它。
请问,您知道 maven 插件可以最小化依赖关系,还是任何独立工具可以做到这一点?
【问题讨论】:
【参考方案1】:你不记得的maven插件可能是Apache Maven Shade Plugin,有minimizeJar
选项。正如 Andreas_D 所注意到的,这不包括加载了 Class.forName
的类,所以你需要 implicity say in configuration,你需要它们。这是我如何让 maven 在我的单个 jar 中包含 jdbc 驱动程序:
<filter>
<artifact>net.sourceforge.jtds:jtds</artifact>
<includes>
<include>**</include>
</includes>
</filter>
【讨论】:
【参考方案2】:对不起,也许我没有清楚地理解问题。混淆器工具(即ProGuard)可以做到这一点,不是吗?它将几个 JAR 打包成一个并剥离未使用的类。如果您不需要混淆/优化(以防止不必要的副作用),则可以禁用它们,启用“收缩”阶段。
【讨论】:
我发现ProGuard已经集成到Android SKD中了,所以我一定会看看它是否符合我的要求。 据我所知,这样的包装会破坏已签名的库 JAR。这可能是严重的劣势。 如果你重新打包库(剥离不需要的东西),那么如果你想要签名的代码,你逻辑上需要自己签名生成的版本。该库不再相同,并且在任何情况下都不应应用相同的签名。【参考方案3】:一般来说,不可能自动选择应用程序使用的所有类。想想我们可以用Class.forName(String name)
做什么,或者我们是否使用依赖注入容器并在外部配置文件中声明类型。
【讨论】:
我知道,但这只是在您使用反射时。 AFAIR 这个工具在没有反射的情况下工作,但不能确定我真的见过它还是只是一个梦;) 不仅在您使用反射时 - 您可以从 url 加载一个类,并且该类可能依赖于您的类路径中的类。也会崩溃。 即使以编译器看不到的方式加载某些代码,它仍然非常有用。那些想要创建最小 jar 的人可以将无法自动找到的类列入白名单。【参考方案4】:我猜如果您使用 Eclipse 来 JAR 项目,它会在 JARing 时提供一些选项来执行此操作 :) 也许会有用。
您还可以在自定义库下收集您使用的库类,并将此用户创建的库包含在项目中。
【讨论】:
以上是关于生成仅包含使用的类的最小化 jar的主要内容,如果未能解决你的问题,请参考以下文章