使用 Proguard 优化后,Jackson Json 解析器在 Android 上的所有对象成员上返回 null

发布于 2024-12-14 02:52:19 字数 3399 浏览 1 评论 0原文

我有一个 Android 应用程序,它使用 Jackson 解析器进行 JSON 解析。在我对类运行 Proguard 后,我开始在反序列化类的每个成员上获取 null 值。 例如,如果我有一个对象:

public class Service{
    private String name;
    private String version;
    ... getters, setters and stuff
}

并且收到一个包含这些对象列表的 JSON:

[{"name":"service1","version":"1.1"},{"name":"service2","version":"1.0"}]

那么我会这样做:

objectMapper.readValue(jsonString,new TypeReference<List<Service>>() {})

我得到的是一个包含 2 个 Service 对象的列表,其中所有成员均为 null。

有什么想法吗?

谢谢

更新,

我错过了 ProGuard 警告:

org.codehaus.jackson.map.deser.EnumSetDeserializer: can't find referenced method 'EnumDeserializer(org.codehaus.jackson.map.deser.EnumResolver)' in class     org.codehaus.jackson.map.deser.EnumDeserializer
org.codehaus.jackson.map.deser.impl.StringCollectionDeserializer: can't find referenced method 'org.codehaus.jackson.map.JsonMappingException instantiationException(java.lang.Class,java.lang.Exception)' in class org.codehaus.jackson.map.DeserializationContext

用以下命令修复了这些警告:

-dontskipnonpubliclibraryclassmembers

就这样了。

亚历克斯

·P.S.

这是proguard.conf,所有库都是通过Maven插件添加的

-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference

-dontoptimize
-dontnote
-dontskipnonpubliclibraryclasses
-printmapping map.txt
-printseeds seed.txt
-ignorewarnings

-keepclassmembers class * {  @com.google.api.client.util.Key <fields>;}

-keepattributes Signature,RuntimeVisibleAnnotations,AnnotationDefault
-keepattributes *Annotation*

-keepclasseswithmembers public class * {    public static void main(java.lang.String[]);}

-keepclassmembers public class com.anydo.client.model** { * ; }
-keepclassmembers public class com.anydo.common.dto** { * ;}
-keep class com.j256.** {*;}

-dontskipnonpubliclibraryclassmembers


-keepclasseswithmembernames class * {
    native <methods>;
}

-keepclasseswithmembernames class * {
    public <init>(android.content.Context, android.util.AttributeSet);
}

-keepclasseswithmembernames class * {
    public <init>(android.content.Context, android.util.AttributeSet, int);
}

-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

-keep class * implements android.os.Parcelable {
  public static final android.os.Parcelable$Creator *;
}

-keepclassmembers class **.R$* {
    public static <fields>;
}

#ACRA
-keep class org.acra.ACRA {
        *;
}

# keep this around for some enums that ACRA needs
-keep class org.acra.ReportingInteractionMode { *; }
# keep this otherwise it is removed by ProGuard
-keep public class org.acra.ErrorReporter
{
public void addCustomData(java.lang.String,java.lang.String);
}

# keep this otherwise it is removed by ProGuard
-keep public class org.acra.ErrorReporter
{
public org.acra.ErrorReporter$ReportsSenderWorker handleSilentException(java.lang.Throwable);
}

I have an Android app which uses Jackson parser for JSON parsing. After I've ran Proguard on the classes I started to get null values on each and every member of the de-serialized classes.
For example, if I have a object:

public class Service{
    private String name;
    private String version;
    ... getters, setters and stuff
}

and I receive a JSON with list of those objects:

[{"name":"service1","version":"1.1"},{"name":"service2","version":"1.0"}]

then I do:

objectMapper.readValue(jsonString,new TypeReference<List<Service>>() {})

what I get is a list with 2 Service objects where all members are null.

Any ideas?

Thanks

UPDATE

I've missed ProGuard warnings:

org.codehaus.jackson.map.deser.EnumSetDeserializer: can't find referenced method 'EnumDeserializer(org.codehaus.jackson.map.deser.EnumResolver)' in class     org.codehaus.jackson.map.deser.EnumDeserializer
org.codehaus.jackson.map.deser.impl.StringCollectionDeserializer: can't find referenced method 'org.codehaus.jackson.map.JsonMappingException instantiationException(java.lang.Class,java.lang.Exception)' in class org.codehaus.jackson.map.DeserializationContext

fixed those with:

-dontskipnonpubliclibraryclassmembers

and that did it.

Alex

P.S.

Here's the proguard.conf, all the libraries are added by Maven plugin

-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference

-dontoptimize
-dontnote
-dontskipnonpubliclibraryclasses
-printmapping map.txt
-printseeds seed.txt
-ignorewarnings

-keepclassmembers class * {  @com.google.api.client.util.Key <fields>;}

-keepattributes Signature,RuntimeVisibleAnnotations,AnnotationDefault
-keepattributes *Annotation*

-keepclasseswithmembers public class * {    public static void main(java.lang.String[]);}

-keepclassmembers public class com.anydo.client.model** { * ; }
-keepclassmembers public class com.anydo.common.dto** { * ;}
-keep class com.j256.** {*;}

-dontskipnonpubliclibraryclassmembers


-keepclasseswithmembernames class * {
    native <methods>;
}

-keepclasseswithmembernames class * {
    public <init>(android.content.Context, android.util.AttributeSet);
}

-keepclasseswithmembernames class * {
    public <init>(android.content.Context, android.util.AttributeSet, int);
}

-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

-keep class * implements android.os.Parcelable {
  public static final android.os.Parcelable$Creator *;
}

-keepclassmembers class **.R$* {
    public static <fields>;
}

#ACRA
-keep class org.acra.ACRA {
        *;
}

# keep this around for some enums that ACRA needs
-keep class org.acra.ReportingInteractionMode { *; }
# keep this otherwise it is removed by ProGuard
-keep public class org.acra.ErrorReporter
{
public void addCustomData(java.lang.String,java.lang.String);
}

# keep this otherwise it is removed by ProGuard
-keep public class org.acra.ErrorReporter
{
public org.acra.ErrorReporter$ReportsSenderWorker handleSilentException(java.lang.Throwable);
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

╭⌒浅淡时光〆 2024-12-21 02:52:19

看起来您正在将不同版本的 jackson-mapper jar 组合到一个项目中。

jackson-mapper-asl-1.7.9.jar 包含

  • org.codehaus.jackson.map.deser.EnumSetDeserializer
  • org.codehaus.jackson.map.deser.EnumDeserializer 和构造函数
    EnumDeserializer(org.codehaus.jackson.map.deser.EnumResolver)

jackson-mapper-asl-1.9.2.jar 包含

  • org.codehaus.jackson.map.deser.std.EnumSetDeserializer
  • org.codehaus.jackson.map.deser.EnumDeserializer带构造函数
    EnumDeserializer(org.codehaus.jackson.map.util.EnumResolver)

请注意 EnumSetDeserializer 的不同包和 EnumDeserializer 的不同构造函数。 ProGuard 无法解析 1.7.9 EnumSetDeserializer 对同一类路径上 1.9.2 EnumDeserializer 的构造函数的引用,并且它正确地对此发出警告。

It looks like you're combining different versions of the jackson-mapper jar in a single project.

jackson-mapper-asl-1.7.9.jar contains

  • org.codehaus.jackson.map.deser.EnumSetDeserializer
  • org.codehaus.jackson.map.deser.EnumDeserializer with constructor
    EnumDeserializer(org.codehaus.jackson.map.deser.EnumResolver)

jackson-mapper-asl-1.9.2.jar contains

  • org.codehaus.jackson.map.deser.std.EnumSetDeserializer
  • org.codehaus.jackson.map.deser.EnumDeserializer with constructor
    EnumDeserializer(org.codehaus.jackson.map.util.EnumResolver)

Notice the different packages for EnumSetDeserializer and the different constructors for EnumDeserializer. ProGuard can't resolve the reference of the 1.7.9 EnumSetDeserializer to the constructor of the 1.9.2 EnumDeserializer on the same class path, and it rightly warns about it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文