android – Error working with Jackson library post-obfuscation using Proguard-ThrowExceptions

Exception or error:

after scouring through all sorts of queries related to issues w/ obfuscation using Proguard, I’ve come to the point where I feel I might be the only one having this particular issue. Hence, the post.

I have a fairly standard android app which makes use of JSON-based REST calls to exchange data. I make use of the Jackson library to parse the JSON data. Everything had been working flawlessly, until we decided to incorporate obfuscation for our release builds using Proguard. After sorting out a world of callback related problems, I’m finally stuck with a problem related to the Jackson library.

basically, the line ObjectMapper om = new ObjectMapper() – just doesn’t work! I keep getting the following error at that line:

Caused by: java.lang.ExceptionInInitializerError
    at org.codehaus.jackson.map.ObjectMapper.<clinit>(Unknown Source)
    ... 8 more
Caused by: java.lang.NullPointerException
    at org.codehaus.jackson.map.introspect.VisibilityChecker$Std.<init>(Unknown Source)
    at org.codehaus.jackson.map.introspect.VisibilityChecker$Std.<clinit>(Unknown Source)
    ... 9 more

After reading a host of other posts related to including external libraries, making proguard ignore the Jackson library classes, turning on and off optimization and shrinking flags, I’m just clueless right now.

The various things I’ve included in my proguard.cfg file for Jackson’s sake –

-dontskipnonpubliclibraryclassmembers
-dontoptimize
-dontshrink
-libraryjars xtraLibs/joda-time-1.6.2.jar;xtraLibs/xml-apis.jar;xtraLibs/jsr311-api-0.8.jar;xtraLibs/stax2-api-3.0.0.jar;xtraLibs/httpmime-4.0.1.jar

amongst these, I’ve toggled the dontoptimize and dontshrink flags. However, the result has always been the same.

In all the time I’ve spent in trying to solve this issue, I’ve come to be amazed and awed by the kind of effort gone into the Proguard library. It’s just that when things don’t work, they’re a bit obfuscated.

Proguard version – 4.6

How to solve:

It’s not obvious from the stack trace, but Jackson needs some annotations, which ProGuard removes by default. Cfr. ProGuard manual > Examples > Processing annotations:

-keepattributes *Annotation*,EnclosingMethod

Furthermore, as the ominous package name ‘org.codehaus.jackson.map.introspect’ suggests, Jackson performs introspection on parsed classes to find getters and setters. Without knowing any better, ProGuard may be removing or renaming these, because your code might not use them explictly. You may have to keep them explicitly, e.g.:

-keep public class mydatapackage.** {
  public void set*(***);
  public *** get*();
} 

Leave a Reply

Your email address will not be published. Required fields are marked *