jackson + ProGuard : can't deserialize class that uses custom deserializer

标签 jackson proguard

我的应用使用 Jackson。我得到的最小化构建主要使用此配置:

# don't obfuscate Jackson classes
-keep class com.fasterxml.** { *; }

# don't strip runtime annotations
-keepattributes RuntimeVisibleAnnotations

# keep members with Jackson annotations
-keepclassmembers public class * {
     @com.fasterxml.jackson.annotation.JsonCreator *;
     @com.fasterxml.jackson.annotation.JsonProperty *;
}

但是最小化构建仍然无法反序列化一个使用自定义反序列化器的类,而自定义反序列化器又使用工厂。工厂、反序列化器和映射器都是由 Dagger2 生产的。错误是:

com.fasterxml.jackson.databind.JsonMappingException: No suitable constructor found for type [simple type, class com.mycompany.myapp.c.y]: can not instantiate from JSON object (missing default constructor or creator, or perhaps need to add/enable type information?)
            at [Source: N/A; line: -1, column: -1]
            at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(Unknown Source)
            at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(Unknown Source)
            at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(Unknown Source)
            at com.fasterxml.jackson.databind.ObjectMapper._readValue(Unknown Source)
            at com.fasterxml.jackson.databind.ObjectMapper.readValue(Unknown Source)
            at com.fasterxml.jackson.databind.ObjectMapper.treeToValue(Unknown Source)
            at com.mycompany.myapp.c.x.a(Unknown Source)
            at com.mycompany.myapp.c.x.a(Unknown Source)
            at com.mycompany.myapp.c.x.deserialize(Unknown Source)
            at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(Unknown Source)
            at com.fasterxml.jackson.databind.ObjectMapper.readValue(Unknown Source)
            at com.mycompany.myapp.c.ag.d(Unknown Source)
            at com.mycompany.myapp.c.ag.a(Unknown Source)
            at com.mycompany.myapp.c.at.run(Unknown Source)
            at android.os.Handler.handleCallback(Handler.java:605)
            at android.os.Handler.dispatchMessage(Handler.java:92)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:4508)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:511)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:809)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:576)
            at dalvik.system.NativeStart.main(Native Method)

错误消息表明我的类缺少默认构造函数,它确实缺少默认构造函数,因为实例是由自定义反序列化器使用工厂创建的。这在我禁用 ProGuard 时工作正常。我需要做什么才能让它与 ProGuard 一起工作?

最佳答案

我无意中发现了这个方便的故障排除技术:

-keepnames class * { *; }

这揭示了真正的罪魁祸首是我的自定义反序列化器中的私有(private)静态嵌套类。解决方案是从此选项的类说明符中删除 public:

-keepclassmembers class * {
     @com.fasterxml.jackson.annotation.JsonCreator *;
     @com.fasterxml.jackson.annotation.JsonProperty *;
}

关于 jackson + ProGuard : can't deserialize class that uses custom deserializer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35877540/

相关文章:

java - 在 neo4j 服务器扩展中使用 JSON

android - proguard 错误?删除日志

android - AsyncTask.doInBackground - Android Scala 项目中抽象方法未实现错误

java - Spring Boot - 自定义 JSON 序列化

java - 是否可以使用Jackson从Pojo获取值(value)

java - 有没有一种方法,例如使用 @JsonFilter 来仅打印 HashMap 的值?

ant - ProGuard Ant 任务的多个配置文件

android - 反射在签名构建 Android 中失败

android - Proguard 不混淆类名,只混淆方法

java - 为属性反序列化具有多种类型的 JSON