当我们准备分发时,我正在通过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
答案 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.*