【问题标题】:proguard causing EnumMap NPE on dynamically declared methodproguard 在动态声明的方法上导致 EnumMap NPE
【发布时间】:2013-11-11 21:10:43
【问题描述】:

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

【问题讨论】:

  • 我不知道 Proguard,但我敢猜测它混淆了 my.package.info.inventory.Inventory,而 getHandlerList() 以某种方式引用了它。应用程序运行时,由于混淆,缺少所需的Inventory
  • 似乎一直在建议我将这些文件标记为单独放置,但我不可能标记与事件相关的所有内容,否则我的一半应用程序将保持原样。跨度>
  • 这个 API 库是否被外部调用,I.E.从 JAR 之外?如果是这样,那么混淆可能无论如何都不是一种选择。
  • 不,它们是内部使用的类,但我认为将事件处理程序/管理器库移动到单独的库是可能的,同时保留实际的单个事件类......虽然我没有不知道现有的类是否仍会中断。

标签: java maven proguard


【解决方案1】:

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

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

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

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

请参阅 ProGuard 文档 > 疑难解答 > 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.*

【讨论】:

    【解决方案2】:

    我只是在 EnumMap 构造函数中有相同的 NullPointerException 并且可以使用以下方法修复它:

    -keepclassmembers enum * {
       public static **[] values(); 
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-02-06
      • 1970-01-01
      • 2016-09-16
      • 2020-07-12
      • 2014-09-14
      • 2014-06-17
      • 2022-11-23
      • 1970-01-01
      相关资源
      最近更新 更多