9

I'm strugling with using jackson-dataformat-xml on android

I have some very basic code that works fine on oracle jre

JacksonXmlModule module = new JacksonXmlModule();
module.setDefaultUseWrapper(false);
XmlMapper xmlMapper = new XmlMapper(module);

First I tried official documentation adapted for gradle (by me, not sure if done correctly):

compile 'com.fasterxml.jackson.core:jackson-core:2.5.4'
compile 'com.fasterxml.jackson.core:jackson-annotations:2.5.4'
compile 'com.fasterxml.jackson.core:jackson-databind:2.5.4'
compile 'com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.5.4'

compile 'org.codehaus.woodstox:woodstox-core-asl:4.4.1'
compile 'javax.xml.stream:stax-api:1.0-2'

Result: gradle fails build time about bundling corelibraries into an application

...
:app:preDexDebug
trouble processing "javax/xml/stream/EventFilter.class":
Ill-advised or mistaken usage of a core class (java.* or javax.*)
when not building a core library.
...

2nd attempt trying to follow Sean's answer (Basicly he repackages corelibs with prefix names and rebuilds jackson-dataformat-xml to use the prefixed names)

compile 'com.fasterxml.jackson.core:jackson-core:2.1.2'
compile 'com.fasterxml.jackson.core:jackson-annotations:2.1.2'
compile 'com.fasterxml.jackson.core:jackson-databind:2.1.2'
// Repackaged XML-specific libraries
compile 'edu.usf.cutr.android.xml:jackson-dataformat-xml-android:2.1.2'
compile 'edu.usf.cutr.android.xml:stax2-api-android:3.1.1'
compile 'edu.usf.cutr.android.xml:stax-api-android:1.0-2'
compile 'edu.usf.cutr.android.xml:aalto-xml-android:0.9.8'

And build time failed on duplicates

Duplicate files copied in APK META-INF/services/com.fasterxml.jackson.core.ObjectCodec

so added:

packagingOptions {
    ...
    exclude 'META-INF/services/com.fasterxml.jackson.core.JsonFactory'
    exclude 'META-INF/services/com.fasterxml.jackson.core.ObjectCodec'
}

When adding the exclusions it builds and deploys, but fails runtime on below stackdump (AFAIK it cant find the SAX provider, even tho it is added to the classpath to my understanding)

edu.usf.cutr.javax.xml.stream.FactoryConfigurationError: Provider com.bea.xml.stream.MXParserFactory not found
            at edu.usf.cutr.javax.xml.stream.FactoryFinder.newInstance(FactoryFinder.java:72)
            at edu.usf.cutr.javax.xml.stream.FactoryFinder.find(FactoryFinder.java:176)
            at edu.usf.cutr.javax.xml.stream.FactoryFinder.find(FactoryFinder.java:92)
            at edu.usf.cutr.javax.xml.stream.XMLInputFactory.newInstance(XMLInputFactory.java:136)
            at com.fasterxml.jackson.dataformat.xml.XmlFactory.<init>(XmlFactory.java:97)
            at com.fasterxml.jackson.dataformat.xml.XmlFactory.<init>(XmlFactory.java:85)
            at com.fasterxml.jackson.dataformat.xml.XmlFactory.<init>(XmlFactory.java:82)
            at com.fasterxml.jackson.dataformat.xml.XmlMapper.<init>(XmlMapper.java:46)

What is the proper way to move forward on either #1 or #2?

Community
  • 1
  • 1
Aksel Willgert
  • 11,367
  • 5
  • 53
  • 74
  • FYI - I added a few edits to my first answer. I've been troubleshooting the same (?) problem on another question - http://stackoverflow.com/questions/30968735/using-com-bea-xml-stream-package-on-android/31139616#31139616. – Sean Barbeau Jul 13 '15 at 21:56

3 Answers3

3

Number 2 is the correct approach (Android doesn't like it when you include classes in the official Java package namespace - but then again, I wrote the original answer so I'm biased ;) ).

I believe the FactoryConfigurationError: Provider com.bea.xml.stream.MXParserFactory not found error is due to a bug in the Android build tools. In previous versions of ADT for Eclipse and Gradle plugin < 0.7.0 the /META-INF/* files are stripped from the JARs during the build process. It seems like >= v0.7.0 shouldn't have the problem according to Google, but from others' reports it sounds like it still may be problematic, and could potentially remove the META-INF/services/javax.xml.stream.XMLInputFactory file, which is required for the platform to register Aalto.

Try the workaround mentioned in AOSP issue 59658 comment 22:

  1. right click on /src/main (where you have /java and /res folders),
  2. select New > Folder > Java Resources Folder,
  3. click Finish (do not change Folder Location),
  4. right click on new /resources folder,
  5. select New > Directory
  6. enter "META-INF" (without quotes),
  7. right click on /resources/META-INF folder,
  8. select New > Directory
  9. enter "services" (without quotes)
  10. copy any file you need into /resources/META-INF/services

For you, in step 10 above you'd need to copy this file into /resources/META-INF/services. In case the file link is broken in the future, the name of the file is javax.xml.stream.XMLInputFactory and it consists of a single line:

com.fasterxml.aalto.stax.InputFactoryImpl

EDIT

If you get a "Error:duplicate files during packaging of APK... Path in archive: META-INF/services/javax.xml.stream.XMLInputFactory", you can try telling Gradle to keep the first occurrence with:

android {
  packagingOptions {
    pickFirst 'META-INF/services/javax.xml.stream.XMLInputFactory'
  }
}

EDIT 2

This bug may be affecting "pickFirst". Please make sure you're running the latest version of Android Studio, and update your local tools and Android Gradle plugin to make sure you're running the most recent version of the tools. This may be fixed in Android Studio 1.3 RC1.

Sean Barbeau
  • 11,496
  • 8
  • 58
  • 111
  • Dude, you're amazing. Thanks. – Dogcat Dec 25 '15 at 07:44
  • Any updates on this question since this time? I tried this steps, but it doesn't help to fix an issue – anber Apr 06 '16 at 08:18
  • @anber Are you getting the exact same stack trace as in this question? – Sean Barbeau Apr 06 '16 at 14:40
  • 1
    Yes, the exact same stack trace. Maybe something like this can help - https://github.com/jamesagnew/hapi-fhir/issues/199 ? – anber Apr 07 '16 at 06:54
  • This AOSP issue is still open - https://code.google.com/p/android/issues/detail?id=158630. I think that's the problem - please star it. After that is fixed, it may work correctly. – Sean Barbeau Apr 07 '16 at 14:14
  • @SeanBarbeau Your dropbox file is no longer accessible. Could you describe what was in that file and how you've created it? I've tried plain java source to no avail, should it be a .class file? – Agent_L Nov 20 '18 at 09:46
  • @Agent_L whoops! Try https://www.dropbox.com/s/3w694gqqwilbh4k/javax.xml.stream.XMLInputFactory?dl=0, that should work. I'm on mobile now but will try to update post with content inline later. – Sean Barbeau Nov 21 '18 at 00:07
  • @Agent_L I just updated the answer with the file name and contents in-line. – Sean Barbeau Nov 27 '18 at 02:37
0

I have attempted to add XmlPull support to jackson xml. Find the forked project here:

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

Currently, only supported for version 2.9.6. (clone the branch jackson-dataformat-xml-2.9.6-XmlPull)

Sorry, I am not able to provide detailed documentation due to time constraints. If you have knowledge of git and maven to pull a specific branch and build the jar, then it should be relatively easy.

praveenp
  • 41
  • 1
  • 3
-3

To those who will be in need of this in the future: first integrate Jitpack in Your Android app, following their instructions: https://jitpack.io/

Then paste teh GitHub url of jackson-dataformat-xml on Jitpack sites' corresponding text box. GitHub url is: https://github.com/FasterXML/jackson-dataformat-xml. That's it! Enjoy the result. :)

Eric Aya
  • 69,473
  • 35
  • 181
  • 253
Victor
  • 147
  • 1
  • 1
  • 8