34

I need to parse the java-objects which are passed through xml. I want to use for these purposes JAXB framework, because I have pre-annotated (using JAXB) java-class.

Is this possible in principle?

InputStream input = entity.getContent();
JAXBContext jc = JAXBContext.newInstance(new Class[] {Response.LoginResponse.class});
Unmarshaller un = jc.createUnmarshaller();
LoginResponse response = (LoginResponse)un.unmarshal(input);

in line 4, I have a warning: "unable to resolve static method 282 JAXBContext ... " and then VM crashes

Any ideas on how to solve this problem?

Bo Persson
  • 90,663
  • 31
  • 146
  • 203
Dmytro Boichenko
  • 5,217
  • 3
  • 28
  • 31
  • 1
    I've repackaged JAXB. See [this blog](http://www.docx4java.org/blog/2012/05/jaxb-can-be-made-to-run-on-android/) for details. – JasonPlutext May 18 '12 at 01:45

2 Answers2

29

I'm not exactly resolving your problem, but JAXB isn't included in android by default and the library will cost you 9(!) MB of your apk. Try SimpleXML instead. It has similiar abilities and much more lightweight.

Vladimir Ivanov
  • 42,730
  • 18
  • 77
  • 103
  • 7
    I want to note, that I already have pre-annotated (using JAXB) java-classes. If I will use SimpleXML I need re-annotate classes. This is unacceptable in my project. – Dmytro Boichenko Mar 29 '11 at 07:35
  • But SimpleXML doesn't fully supports XML Schema. – Dmytro Boichenko Apr 08 '11 at 09:21
  • SimpleXML don't correctly work with null-objects: [http://stackoverflow.com/questions/5536896/simplexml-deserialization-error-in-android](http://stackoverflow.com/questions/5536896/simplexml-deserialization-error-in-android) – Dmytro Boichenko May 03 '11 at 11:33
  • 2
    There are a lot of issues with SimpleXML that I cannot justify the tradeoff, such as forcefully inserting certain attributes (which is invalid with some schemas). If my producer/consumer were both SimpleXML, fine, but it's not. – Kevin Mangold Mar 27 '13 at 19:18
  • 1
    Kevin Mangold, there are attributes in annotations, such as "strict" one, that allows you ignore missing attributes. – Vladimir Ivanov Mar 28 '13 at 07:24
  • 2
    Doesn't answer the question - the problem is how to use PRE-ANNOTATED JAXB classes. – Michael Bushe Jun 03 '15 at 15:41
27

I had the same problem of wanting to use a bunch of JAXB classes in the process of parsing XML (and, for me, JSON) web server responses.

I wrote up a wiki page for Parsing XML and JSON on Android, which describes a solution for this problem and guides you through step-by-step.

To be clear - I'd advise using JSON instead of XML on Android whenever possible. There are significant performance advantages for JSON.

To summarize my solution for using JAXB classes for both JSON and XML parsing:

I ended up stripping all annotations and javax.xml.* imports from the JAXB classes (slightly easier than re-annotating classes for SimpleXML - plus, you can also parse JSON responses) to create true POJOs, and then use Jackson with modified versions of the XML libraries that Jackson depends on.

The modification of the XML libraries is necessary because Android doesn't include required XML classes in the platform, and it will complain if you try to include classes in the protected javax.xml namespace as libraries in your project.

I stripped the XML annotations and imports manually initially, but then ended up automating the process via ant scripts.

Luckily, you can automate the XML library modification process. I wrote up a detailed post on Modifying XML libraries for Android (which the full tutorial references) which describes how to move the relevant classes into a new unprotected namespace using the Jar Jar Links utility.

If you want to use Jackson on Android, I've also created a modified version of the jackson-dataformat-android, aalto-xml, stax-api, and stax2-api projects for Android that you can feel free to use.

Here's a sample of what you would include in your pom.xml to include the dependencies via Maven:

<dependencies>              
    <!-- Using Jackson for parsing -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-core</artifactId>
        <version>2.1.2</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.1.2</version>
    </dependency>

    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-annotations</artifactId>
        <version>2.1.2</version>
    </dependency>   
    <!-- XML parsing  -->
    <!-- So many problems with XML and Android...
         Below XML libraries have been modified using JarJar
         and are NOT the same as their J2SE counterparts,
         hence the added "-android" to the artifactId
         See:
         https://github.com/CUTR-at-USF/SiriRestClient/wiki/Modifying-XML-libraries-for-Android
      -->        
    <dependency>
        <groupId>edu.usf.cutr.android.xml</groupId>
        <artifactId>jackson-dataformat-xml-android</artifactId>
        <version>2.1.2</version>
    </dependency>
    <dependency>
        <groupId>edu.usf.cutr.android.xml</groupId>
        <artifactId>stax2-api-android</artifactId>
        <version>3.1.1</version>
    </dependency>
    <dependency>
        <groupId>edu.usf.cutr.android.xml</groupId>
        <artifactId>stax-api-android</artifactId>
        <version>1.0-2</version>
    </dependency>
    <dependency>
        <groupId>edu.usf.cutr.android.xml</groupId>
        <artifactId>aalto-xml-android</artifactId>
        <version>0.9.8</version>
    </dependency>        
</dependencies>    

<repositories>
    <!-- CUTR Android XML libraries Releases -->
    <repository>
      <id>cutr-releases</id>
      <url>https://github.com/CUTR-at-USF/cutr-mvn-repo/raw/master/releases</url>
    </repository>      
</repositories>

See this page for more details using these libraries.

You can download the JAR files from their respective directories here, if you want to include them directly in your project.

You can also check out the open-source "SIRI REST Client" app that uses these libraries for a working example.

EDIT

If you're using Gradle, your build.gradle would look like this:

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:0.9.+'
    }
}
apply plugin: 'android'

repositories {
    mavenCentral()
    maven {
        // CUTR SNAPSHOTs
        url "https://github.com/CUTR-at-USF/cutr-mvn-repo/raw/master/snapshots"
    }
    maven {
        // CUTR Releases
        url "https://github.com/CUTR-at-USF/cutr-mvn-repo/raw/master/releases"
    }
}

android {
    compileSdkVersion 19
    buildToolsVersion "19.0.1"
    ...
}

dependencies {
    ...
    // Normal Jackson libraries
    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'
    ...       
}
Community
  • 1
  • 1
Sean Barbeau
  • 11,496
  • 8
  • 58
  • 111
  • 1
    If you are here to look for an android compatible version of jackson for xml parsing, you probably want to read [this page](https://github.com/CUTR-at-USF/SiriRestClient/wiki/Modifying-XML-libraries-for-Android). Sean was so kind to provide the modified library [jackson-dataformat-xml-android](https://github.com/CUTR-at-USF/cutr-mvn-repo/raw/master/releases/edu/usf/cutr/android/xml/jackson-dataformat-xml-android/2.1.2/jackson-dataformat-xml-android-2.1.2.jar). Use that along with `jackson-core`, `jackson-anntotation` and `jackson-databind`, and be happy :) – sulai Dec 02 '13 at 15:13
  • 1
    Thanks for the reminder @sulai! I believe I wrote this post before that library was published, so I'll update my above answer to include it. Glad it was useful! – Sean Barbeau Dec 02 '13 at 15:33
  • 1
    Someone have the Android Studio gradle equals for this pom.xml? – RoundSparrow hilltx May 02 '14 at 19:48
  • @RoundSparrowhilltx I believe I do, I'll post it shortly. – Sean Barbeau May 02 '14 at 19:53
  • @SeanBarbeau thanks - so far I have: 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' Trying to get the repository maven link working. – RoundSparrow hilltx May 02 '14 at 20:01
  • @RoundSparrowhilltx Ok, just updated answer. Please give that a shot and let me know if it works. I actually haven't used these exact artifacts in a Gradle build yet, but the rest of the file is patterned off of other artifacts we're hosting in the same repo, so it should work. – Sean Barbeau May 02 '14 at 20:33
  • I've been trying to use the gradle implementation above, but I get the following error. Does anybody know what is going wrong, I would be most grateful java.lang.RuntimeException: edu.usf.cutr.javax.xml.stream.FactoryConfigurationError: Provider com.bea.xml.stream.MXParserFactory not found at dagger.internal.plugins.reflect.ReflectiveModuleAdapter$ProviderMethodBinding.get(ReflectiveModuleAdapter.java:137) at dagger.internal.Linker$SingletonBinding.get(Linker.java:301) at dagger.internal.plugins.reflect.ReflectiveAtInjectBinding.injectMembers(ReflectiveAtInjectBinding.java:116) – Smalesy May 18 '14 at 11:53
  • @Smalesy Looks like potentially an issue with Dagger? – Sean Barbeau May 18 '14 at 13:44
  • Thanks for the quick reply. I took the code out of Dager and unfortunately I still get the error. I had the following in my build file: configurations { all*.exclude module: 'stax' all*.exclude module: 'stax-api' all*.exclude module: 'xpp3' } However removing them results in this build error: – Smalesy May 18 '14 at 15:17
  • Error:Execution failed for task ‘:test-android:preDexDebug'. > com.android.ide.common.internal.LoggedErrorException: Failed to run command: /Users/.../android-sdks/build-tools/19.0.1/dx --dex --output /Users/.../build/pre-dexed/debug/stax-api-1.0.1-.jar /Users/.../.gradle/caches/modules-2/files-2.1/stax/stax-api/1.0.1//stax-api-1.0.1.jar Error Code: 1 Output: trouble processing "javax/xml/stream/events/StartElement.class": Ill-advised or mistaken usage of a core class (java.* or javax.*) when not building a core library. – Smalesy May 18 '14 at 15:17
  • @Smalesy Looks like you're still trying to use javax.xml.* classes in your project. Trying reading https://github.com/CUTR-at-USF/SiriRestClient/wiki/Modifying-XML-libraries-for-Android#the-problem---xml-parser-implementation-on-android – Sean Barbeau May 19 '14 at 13:21
  • Thanks @SeanBarbeau I did read through that doc originally but think I will have another read to see if I can track it down. If I'm still having problems I'll start a new question to stop hijacking your thread :) – Smalesy May 20 '14 at 14:09
  • Sounds good :). Please comment here with a link to a new question so I can follow it, if you open another one. There could be differences with Gradle/Android Studio, as I haven't actually tested the above on Gradle myself. – Sean Barbeau May 20 '14 at 14:38
  • @SeanBarbeau I want to do the same for Apache POI library for java, I downloaded the zip file and read your github post. But I still have doubt how do I modify my poi.jar file using JarJar to change the package dependencies for Stack api ? Please help. If you want I can post a separate question for the Issue – kritya Jun 21 '15 at 17:56
  • @kritya Yes, please post separate question and post the link to it here. – Sean Barbeau Jun 21 '15 at 18:59
  • @SeanBarbeau I solved that problem. But I have another problem for using android doesn't contains more dependent packages for getting Stack to work. Like it does not have com.bea.xml.steam package. Link to the question: http://stackoverflow.com/questions/30968735/using-com-bea-xml-stream-package-on-android – kritya Jun 21 '15 at 20:02
  • @SeanBarbeau: I saw from your github page (https://github.com/CUTR-at-USF/cutr-mvn-repo/tree/master/releases/edu/usf/cutr/android/xml) that you have new versions of your special libraries. For example, your `jackson-dataformat-xml-android` library is currently at `2.6.2` (whereas your original posting cited version `2.1.2`). Is it safe to use the very latest version of your libraries? I guess you must have some automated system of pulling the latest Jackson releases (also at 2.6.2 at this time) and modifying them. – stackoverflowuser2010 Sep 26 '15 at 04:43
  • @stackoverflowuser2010 We unfortunately don't have an automated system to do the update, which is why we hadn't updated past 2.1.2 for some time. I'm not actively using Jackson for XML parsing in any production applications, so we haven't had the need for it (we use JSON instead). A user contributed the updated libraries to 2.6.2 (https://github.com/CUTR-at-USF/cutr-mvn-repo/pull/1), so I can't personally vouch for them. But, feel free to try them out and see how they work. – Sean Barbeau Sep 26 '15 at 05:09
  • Hi Guys, I am implementing eWay java server SDK but it is giving Failed resolution of: Ljavax/xml/bind/annotation/XmlElement error. Please help me – Rushi M Thakker Apr 14 '17 at 09:52
  • @Rushi please open a new SO question with the details of your problem and post the link here. – Sean Barbeau Apr 14 '17 at 11:47