proguard导致动态声明的方法上的EnumMap NPE [英] proguard causing EnumMap NPE on dynamically declared method

查看:156
本文介绍了proguard导致动态声明的方法上的EnumMap NPE的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在准备分发时,我正在通过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的fastevents

解决方案

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

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

请参阅ProGuard文档>故障排除> 注意:...访问字段/方法' ..."动态地

ProGuard还注意到,您的配置保留了一个类的构造函数,但并不保留其所有参数类型.对于某些类型的反射,您还需要保留这些参数类型.您很有可能只是通过使用通配符不小心保留了构造函数.那会有点草率,但无害.

请参阅ProGuard文档>故障排除> 注意:配置保留入口点'. ",而不是描述符类"..."

要解决NullPointerException,您必须知道HandlerList中的代码中发生了什么.您可以通过以下方式让ProGuard保留行号:

-renamesourcefileattribute SourceFile
-keepattributes SourceFile,LineNumberTable

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

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

I'm adding obfuscation via proguard/maven to a java application as we prepare it for distribution. During the process, it errors out with:

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

It then lists a dozen classes with that method with Maybe this is... and it recommends using -keep to avoid the problem.

When I do add -keep public class my.package.info.eventlib.HandlerList { *; } to the build process, the error goes away, but I see the following notices:

[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'

When I run the application, it errors out with an NPE (which it doesn't do when run without obfuscation):

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)

It's all tied to the events. How can I resolve this without telling proguard to keep everything tied to them?

Here's a full example of the original error: http://pste.me/m9BsY/

The event system is based on lahwran's fastevents

解决方案

ProGuard notes that your code accesses a method dynamically, but it can't figure out which method it is precisely. If it renames or even removes the method, the reflection in your code will fail, so you need to keep the right method(s). Maybe you want to keep all of the listed candidates:

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

See the ProGuard documentation > Troubleshooting > Note: ... accesses a field/method '...' dynamically

ProGuard also notes that your configuration preserves the constructor of a class, but not all of its argument types. For some types of reflection, you also need to preserve these argument types. It's more likely that you're just accidentally keeping the constructor by using a wildcard. That would be a bit sloppy, but harmless.

See the ProGuard documentation > Troubleshooting > Note: the configuration keeps the entry point '...', but not the descriptor class '...'

For solving the NullPointerException, you have to know what is happening in your code in HandlerList. You can let ProGuard preserve line numbers with

-renamesourcefileattribute SourceFile
-keepattributes SourceFile,LineNumberTable

If the code or the library performs reflection, and the original class names are important, you may need to preserve them. E.g. if the names of the event classes matter:

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

这篇关于proguard导致动态声明的方法上的EnumMap NPE的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆