给定一个常规的java gradle项目,我们有一些在jar清单中定义的入口main方法,以及一堆依赖项。
现在通常在我们创建分发时,我们可能会使用应用程序插件,并且有一些像这样的结构作为输出
/bin (some splatform specific scripts that point to our jar)
/lib (our jar + all dependencies with their dependencies etc...)
问题在于,即使我们只使用了直接依赖项中的几个类,它们和所有传递依赖项最终都会出现在分布中。例如,从100M的发行版中,1M实际上是可能运行的代码,可能与我们的应用程序有任何关系......
像proguard这样的工具可以通过各种优化来缩小特定jar中的代码,但是如果代码未使用则无关紧要。未使用我的意思是主方法是jar的入口点,并且根据main中的代码,它可能永远不会使用实际应用程序jar中的大部分代码而且库库中的代码更多......
我们的目标是创建这个只有实际将使用的代码的1M jar,考虑jar清单中的主要方法...
我搜索了很多,但找不到任何解决方案,proguard非常接近,但我找不到任何方法让它只关心代码的具体流程而不是所有代码。
有没有可以做到这一点的工具?
答案 0 :(得分:1)
您对ProGuard所做的描述是错误的:
像proguard这样的工具可以缩小特定jar中的代码 优化,但它不关心代码是否未使用。未使用的i 意味着主要的方法是jar的入口点,并取决于 main中的代码可能永远不会使用大部分代码 实际应用jar和库罐中的更多......
您所描述的unused code
正是ProGuard在缩小步骤中所做的。从种子开始(在您的情况下是main
方法),它将查找正在使用的任何类/方法并删除其他所有内容。
如果保留太多类,很可能是由于某些-keep
规则。你必须根据需要调整它们。例如,如果第三方库不使用反射,则不需要保留。
ProGuard还可以在优化步骤中移除dead code
:根据流量分析永远不会执行的方法中的任何指令都将被删除。这种技术在指令级上运行,而收缩则在类级别上运行。