Search code examples
androidjacksonfasterxmljackson-dataformat-xmlxmlmapper

How to fix XmlMapper exception - java.lang.VerifyError: com.fasterxml.jackson?


Android Studio 2.2.2
Compile SDK Android 7.1.1
Build Tools: 25.0.0
Gradle version: 2.14.1
Min SDK: 19
Target SDK: 25

I encountered an issue with jackson-dataformat-xml-2.8.5.jar when attempting to execute this:

 JacksonXmlModule module = new JacksonXmlModule();
 ObjectMapper xmlMapper = new XmlMapper(); //This line

throws the following exception

E/AndroidRuntime: FATAL EXCEPTION: Thread-418
              Process: cb.myAppName, PID: 29744
              java.lang.VerifyError: com/fasterxml/jackson/dataformat/xml/XmlFactory
                  at com.fasterxml.jackson.dataformat.xml.XmlMapper.<init>(XmlMapper.java:49)
                  at cb.myAppName.Core.GenerateReturnXMLFile(Core.java:863)
                  at cb.myAppName.RouteScreenActivity$4.run(RouteScreenActivity.java:305)
                  at java.lang.Thread.run(Thread.java:841)

From what I researched, it has to do with a binary incompatibility that was introduced in Jackson 1.3. As stated by Tatu Saloranta in his old blog which sadly is no longer online.

I have always valued compatibility quite highly, at least for any "non beta" release (1.0 and above). As a result, the idea has been that any 1.x release would be simple plug-and-play over previous one. This does work for patch releases; but it turns out that not all minor releases have worked this way. For example, versions 1.2 and 1.3 have some unexpected incompatibilities.

Problem is this: although most commonly binary compatibility is a harder goal than source compatibility -- that is, if you break source compatibility, you are almost guaranteed to break binary compatibility -- it is not strictly so. Specifically, it is quite possible to make certain changes that are source compatible, but that are NOT binary compatible.

Specific case in point is that of changing a method that returns nothing ("void method") into method that returns something does not break compilation. But it does actually break binary compatibility. UGH.

And this is exactly what happened when I decided that it would be nice to make ObjectMapper follow "fluent" pattern, to allow for chaining of configuration method calls. This would be nice, if it was not this "hidden" API change...

Not quite sure how to correct this though since i'm fairly new to android development.

I already made sure to use same version of Jackson across the board as you can see in my list of dependencies from the app/build.gradle, is there something else I may be missing?

dependencies {
    compile fileTree(include: ['*.jar'], exclude: ['com.symbol.emdk.jar'], dir: 'libs')
    compile files('../libs/json-20151123.jar')
    provided files('../libs/com.symbol.emdk.jar')
    compile files('../libs/slf4j-api-1.7.6.jar')
    compile files('../libs/logback-android-1.1.1-4.jar')
    compile files('../libs/sun.misc.BASE64Decoder.jar')
    compile files('../libs/ZSDK_ANDROID_API.jar')
    compile 'com.android.support:appcompat-v7:22.2.1'
    compile 'com.android.support:support-v7:22.2.0'
    compile 'com.google.code.ksoap2-android:ksoap2-android:3.6.0'
    compile 'com.google.code.gson:gson:2.4'
    compile 'org.apache.directory.studio:org.apache.commons.io:2.4'
    compile 'org.joda:joda-money:0.11'
    compile 'org.apache.directory.studio:org.apache.commons.lang:2.6'
    compile 'com.google.android.gms:play-services-appindexing:9.8.0'
    compile 'org.greenrobot:eventbus:3.0.0'
    compile 'com.fasterxml.jackson.core:jackson-core:2.8.5'
    compile 'com.fasterxml.jackson.core:jackson-databind:2.8.5'
    compile 'com.fasterxml.jackson.datatype:jackson-datatype-joda:2.8.5'
    compile 'com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.8.5'
    compile 'com.github.gcacace:signature-pad:1.2.0'
}

As per the official FasterXML Jackson github page, the extension i'm using should be supported...

XML: supports XML; provides both streaming and databind implementations. Similar to JAXB' "code-first" mode (no support for "XML Schema first", but can use JAXB beans)

https://github.com/FasterXML/jackson-dataformat-xml

This issue was also reported on the project's github page but no real solution was reached. -- github.com/FasterXML/jackson-dataformat-xml/issues/116

UPDATE: I used jarjar on the following dependencies:

compile files('../libs/cb-joda-time-2.9.6.jar')
compile files('../libs/cb-joda-money-0.12.jar')
compile files('../libs/cb-jackson-dataformat-xml-2.8.5.jar')
compile files('../libs/cb-jackson-datatype-joda-2.8.5.jar')
compile files('../libs/cb-java-json-0.13.0.jar')
compile files('../libs/cb-json-20160212.jar')

Also upgraded every single dependency to latest version as well as my appcompat and support api.

The error continues -

java.lang.VerifyError: cb/com/fasterxml/jackson/dataformat/xml/XmlFactory
                      at cb.com.fasterxml.jackson.dataformat.xml.XmlMapper.<init>(XmlMapper.java:49)

Hopefully someone can shine some light on this, not sure what is causing this...


Solution

  • After some research and tips from user aha I was able to further identify how to correct this. I haven't had time to test it since I ended up taking a different route and using SimpleXML library instead which works great for what I needed to do.

    I will update this answer with more details when I do get around to testing it but here are some ways to attempt and correct this:

    • Include Stax as a dependency: github.com/FasterXML/jackson-dataformat-xml#android-quirks
    • Execute gradle dependencies. Gradle will then display the actual dependency tree that it has used to compile and package your app. The generated dependency tree might be different than the dependencies you'd declared, e.g. because of transitive dependencies. -Thanks aha

    This is the original issue at github: github.com/FasterXML/jackson-dataformat-xml/issues/116