proguard在动态声明的方法上导致EnumMap NPE

时间:2013-11-11 21:10:43

标签: java maven proguard

当我们准备分发时,我正在通过proguard / maven将混淆添加到java应用程序中。在此过程中,它出错:

Note: ...eventlib.EventManager accesses a declared method 'getHandlerList()' dynamically

然后使用Maybe this is...列出了使用该方法的十几个类,并建议使用-keep来避免此问题。

当我在构建过程中添加-keep public class my.package.info.eventlib.HandlerList { *; }时,错误消失了,但我看到以下注意事项:

[proguard] Note: the configuration keeps the entry point 'events.TransactionEvent { TransactionEvent(my.package.info.inventory.Inventory,my.package.info.inventory.Inventory$TransactionType,my.package.info.inventory.ItemDefinition,short); }', but not the descriptor class 'my.package.info.inventory.Inventory'

当我运行应用程序时,它会出现NPE错误(在没有混淆的情况下运行时不会这样做):

Caused by: java.lang.NullPointerException
at java.util.EnumMap.<init>(EnumMap.java:113)
at my.package.info.eventlib.HandlerList.<init>(Unknown Source)
at my.package.info.events.CollisionEvent.<clinit>(Unknown Source)

这一切都与事件有关。如何解决这个问题而不告诉proguard保持一切与他们联系?

以下是原始错误的完整示例:http://pste.me/m9BsY/

事件系统基于lahwran's fastevents

1 个答案:

答案 0 :(得分:1)

ProGuard指出您的代码会动态访问某个方法,但它无法确定哪种方法是精确的。如果它重命名甚至删除方法,代码中的反射将失败,因此您需要保留正确的方法。也许你想保留所有列出的候选人:

-keepclassmembers class * {
    *** getHandlerList();
}

请参阅ProGuard文档&gt;疑难解答&gt; Note: ... accesses a field/method '...' dynamically

ProGuard还指出,您的配置会保留类的构造函数,但不会保留其所有参数类型。对于某些类型的反射,您还需要保留这些参数类型。您更可能只是通过使用通配符意外保留构造函数。这有点草率,但无害。

请参阅ProGuard文档&gt;疑难解答&gt; Note: the configuration keeps the entry point '...', but not the descriptor class '...'

要解决NullPointerException,您必须知道HandlerList中代码中发生了什么。您可以让ProGuard使用

保留行号
-renamesourcefileattribute SourceFile
-keepattributes SourceFile,LineNumberTable

如果代码或库执行反射,并且原始类名称很重要,则可能需要保留它们。例如。如果事件类的名称很重要:

-keep class my.package.info.events.*