5

For getting Apache POI to work on Android, I need to get Stack to work on Android. Following this question:Using JAXB with Google Android and @Sean Barbeau's answer. I successfully converted all the jar's to android compatible ones including the Apache POI library but it still gives me this run time error:

06-22 01:06:52.461  14865-14865/com.quizwiz.sharmakritya.poi E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: com.quizwiz.sharmakritya.poi, PID: 14865
    edu.usf.cutr.javax.xml.stream.FactoryConfigurationError: Provider com.bea.xml.stream.EventFactory 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.XMLEventFactory.newInstance(XMLEventFactory.java:30)
            at org.apache.poi.openxml4j.opc.internal.marshallers.PackagePropertiesMarshaller.<clinit>(PackagePropertiesMarshaller.java:41)
            at org.apache.poi.openxml4j.opc.OPCPackage.init(OPCPackage.java:162)
            at org.apache.poi.openxml4j.opc.OPCPackage.<init>(OPCPackage.java:142)
            at org.apache.poi.openxml4j.opc.Package.<init>(Package.java:37)
            at org.apache.poi.openxml4j.opc.ZipPackage.<init>(ZipPackage.java:87)
            at org.apache.poi.openxml4j.opc.OPCPackage.open(OPCPackage.java:273)
            at org.apache.poi.xslf.usermodel.XMLSlideShow.empty(XMLSlideShow.java:103)
            at org.apache.poi.xslf.usermodel.XMLSlideShow.<init>(XMLSlideShow.java:75)
            at com.quizwiz.sharmakritya.poi.PPT.onCreate(PPT.java:16)
            at android.app.Activity.performCreate(Activity.java:5451)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1093)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2377)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2471)
            at android.app.ActivityThread.access$900(ActivityThread.java:175)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1308)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:146)
            at android.app.ActivityThread.main(ActivityThread.java:5602)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
            at dalvik.system.NativeStart.main(Native Method)

The crux of the whole error is android is missing the package com.bea.xml.stream. How do I resolve this ?

I tried resolving this on my own by downloading an external jar from here. But that gave me strange errors:

06-22 01:10:42.906  20374-20374/com.quizwiz.sharmakritya.poi E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: com.quizwiz.sharmakritya.poi, PID: 20374
    java.lang.RuntimeException: Unable to instantiate application android.support.multidex.MultiDexApplication: java.lang.RuntimeException: Multi dex installation failed (Field dexElementsSuppressedExceptions not found in class dalvik.system.PathClassLoader).
            at android.app.LoadedApk.makeApplication(LoadedApk.java:516)
            at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4703)
            at android.app.ActivityThread.access$1600(ActivityThread.java:175)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1368)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:146)
            at android.app.ActivityThread.main(ActivityThread.java:5602)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
            at dalvik.system.NativeStart.main(Native Method)
     Caused by: java.lang.RuntimeException: Multi dex installation failed (Field dexElementsSuppressedExceptions not found in class dalvik.system.PathClassLoader).
            at android.support.multidex.MultiDex.install(MultiDex.java:178)
            at android.support.multidex.MultiDexApplication.attachBaseContext(MultiDexApplication.java:39)
            at android.app.Application.attach(Application.java:201)
            at android.app.Instrumentation.newApplication(Instrumentation.java:997)
            at android.app.Instrumentation.newApplication(Instrumentation.java:981)
            at android.app.LoadedApk.makeApplication(LoadedApk.java:511)
            at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4703)
            at android.app.ActivityThread.access$1600(ActivityThread.java:175)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1368)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:146)
            at android.app.ActivityThread.main(ActivityThread.java:5602)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
            at dalvik.system.NativeStart.main(Native Method)

Note: removing the com.bea.stax.impl_1.2.0.jar from Gradle Dependencies gets me back to the first error.

Please help me find a way to use the package com.bea.xml.stream on android. UPDATE

The dependencies before your answer in gradle:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 21
    buildToolsVersion "21.1.2"

    packagingOptions{
        exclude 'META-INF/DEPENDENCIES'
        exclude 'META-INF/NOTICE'
        exclude 'META-INF/NOTICE.txt'
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/LICENSE.txt'
    }

    defaultConfig {
        applicationId "com.quizwiz.sharmakritya.poi"
        minSdkVersion 16
        targetSdkVersion 21
        versionCode 1
        versionName "1.0"
        multiDexEnabled true
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}
dependencies {
    compile 'com.android.support:appcompat-v7:21.0.3'
    compile 'com.android.support:multidex:1.0.0'
    compile files('libs/stax-api-android-1.0-2.jar')
    compile files('libs/stax2-api-android-3.1.1.jar')
    //compile files('libs/com.bea.stax.impl_1.2.0.jar')
    compile files('libs/poi-3.12-20150511.jar')
    compile files('libs/poi-ooxml-3.12-20150511.jar')
    compile files('libs/poi-ooxml-schemas-3.12-20150511.jar'){
    exclude group: 'stax', module: 'stax-api'
    }
    compile files('libs/xmlbeans-2.6.0.jar')
    compile files('libs/stax-1.2.0_rc2-dev.jar')
}

UPDATE #2 The error while compilation I get:

    Error:duplicate files during packaging of APK C:\Users\sharmakritya\AndroidStudioProjects\POI\app\build\outputs\apk\app-debug-unaligned.apk
    Path in archive: META-INF/services/javax.xml.stream.XMLInputFactory
    Origin 1: C:\Users\sharmakritya\AndroidStudioProjects\POI\app\build\intermediates\javaResources\debug\META-INF\services\javax.xml.stream.XMLInputFactory
    Origin 2: C:\Users\sharmakritya\.gradle\caches\modules-2\files-2.1\edu.usf.cutr.android.xml\aalto-xml-android\0.9.8\bf4e7339b028f92638b36ab9ac3cc3314a860d1\aalto-xml-android-0.9.8.jar
You can ignore those files in your build.gradle:
    android {
      packagingOptions {
        exclude 'META-INF/services/javax.xml.stream.XMLInputFactory'
      }
    }
Error:Execution failed for task ':app:packageDebug'.
> Duplicate files copied in APK META-INF/services/javax.xml.stream.XMLInputFactory
    File 1: C:\Users\sharmakritya\AndroidStudioProjects\POI\app\build\intermediates\javaResources\debug\META-INF\services\javax.xml.stream.XMLInputFactory
    File 2: C:\Users\sharmakritya\AndroidStudioProjects\POI\app\build\intermediates\javaResources\debug\META-INF\services\javax.xml.stream.XMLInputFactory
Community
  • 1
  • 1
kritya
  • 3,312
  • 7
  • 43
  • 60
  • Actually - did you try repackaging POI into a new JAR, with the same class name swap as you used in the Stax/Aalto JARs? Just noticed that these don't appear to be modified (i.e., they are the desktop JARs) in your dependencies. – Sean Barbeau Jul 01 '15 at 18:44
  • Nope I did modify POI as well. I just didn't put the android tag as the names were getting too big. PS: Proof look at the dump it is from edu.usf.cutr.javax.xml.stream and I did reach this by far cause of that solution provided by you only. – kritya Jul 02 '15 at 07:48
  • Gotcha - ok, so my only other suggestions are in my edited answer below. Let me know if you figure it out! – Sean Barbeau Jul 02 '15 at 13:09
  • 1
    @StaxMan would you be able to take a look at this? In short, kritya is trying to use [Apache POI](https://poi.apache.org/) (which seems to use JSR173 API internally) to parse Microsoft XML documents on Android. kritya has rebundled stax-api and stax2-api for Android, and Apache POI seemed to pick up these classes (see edu.usf.cutr... in stack trace). Problem seems to be that it can't find a provider. How is Aalto or Woodstox normally registered with the platform as a JSR173 provider? XML parsing worked for me on Android, but I was using Jackson. Any wisdom? – Sean Barbeau Jul 08 '15 at 13:28
  • @SeanBarbeau Thanks a lot for that. But I doubt if he would get an notification due to this. Thanks again( well that's all I can say for your great help ha) – kritya Jul 08 '15 at 18:09
  • I pinged @StaxMan via email as well, so hopefully he has a chance to look at this (he's the author of Jackson and intimately familiar with this stuff). Good luck! I'm interested to know if you can get it working. – Sean Barbeau Jul 08 '15 at 19:19
  • @SeanBarbeau I would seriously try to avoid using auto-registration at all. It should indeed work by adding SPI metadata under `META-INF/services/javax.xml.stream.XMLInputFactory` (and 2 others); but given that there is no way to resolve conflicts (if multiple providers), and it has significant overhead, it is generally better to directly instantiate factories. Unfortunately I don't know if POI can be configured or patched to take direct class name or instance. – StaxMan Jul 08 '15 at 19:52
  • Also: BEA's stax implementation is to be avoided as well. It has the most bugs, and there is very little point in using it. A better choice is probably Aalto (https://github.com/FasterXML/aalto-xml), with maven id of group=`com.fasterxml`, artifact=`aalto-xml` – StaxMan Jul 08 '15 at 19:54
  • Thanks @StaxMan! I had also suggested using Aalto. The SPI metdata should already be set if Aalto is bundled as a dependency, though, right? `META-INF/services/javax.xml.stream.XMLInputFactory` is already defined in the Aalto JAR, from a quick look at https://github.com/CUTR-at-USF/cutr-mvn-repo/blob/master/releases/edu/usf/cutr/android/xml/aalto-xml-android/0.9.9/aalto-xml-android-0.9.9.jar. Do we need to add this metadata to another JAR? – Sean Barbeau Jul 08 '15 at 20:31
  • @Sean Sorry but this is getting a bit out of something what is in my comfort zone of understanding of java. Maybe you two can if decide on a solution. You can explain it to me in an easier way lay man way or point me somewhere from where I can read the relevant information. – kritya Jul 09 '15 at 16:25
  • @StaxMan thanks a lot for your help. I am ready to tweek anything around or learn anything if neccessary to get this damned thing working or anroid. But I am afraid I don't understand much of what you advised. – kritya Jul 09 '15 at 16:28
  • @kritya Wrt BEA Stax implementation: just get rid of that package, and try to use Aalto instead. Unfortunately I am not very familiar with Android build tools, but I think Sean B can help wth that – StaxMan Jul 10 '15 at 22:15
  • @SeanBarbeau yes, Aalto does set SPI metadata as well. Should not need to add anywhere else -- however, one can also set System Property to override what jar has; it has precedence. – StaxMan Jul 10 '15 at 22:16
  • Thanks @StaxMan! @kritya I'm not sure why its not working then, when you include Aalto instead of BEA. Can you include the JARs from the CUTR Maven repo from my JAXB answer instead of bundling your local JARs (for Aalto, stax, stax2, etc)? Maybe something went wrong in your rebundling of those libraries. Also, are you using Proguard to obfuscate your app? If so Id turn it off for now. Might help to post your entire build.gradle in the question. – Sean Barbeau Jul 10 '15 at 22:37
  • @SeanBarbeau updated my question. – kritya Jul 11 '15 at 13:16
  • @StaxMan I did try using Aalto but that isn't helping at all. The reason I can think is of that Aalto doesn't contains the class that Stax is looking for. As obviously the package names for both are different. Correct me if I am wrong. So even in normal java( not android) how does the stax api gets to know which implementation to use ? Cus as of my knowledge it would be importing from bea package only. Wouldn't the solution be same in android as well? Thanks. – kritya Jul 13 '15 at 08:33
  • 1
    @kritya Apparently there is a [known issue](https://code.google.com/p/android/issues/detail?id=59658#c10) in Android build tools that may be stripping out the `META-INF/services/javax.xml.stream.XMLInputFactory` from the JAR/APK when building your app. If this file is missing in your build, then Aalto won't be registered as a JSR173 provider, and including Aalto (or any JSR173 provider, including BEA) won't fix your original error. Try my edited answer, which uses CUTR JAR files from Maven repo, and includes a workaround for the Android build tools bug. – Sean Barbeau Jul 13 '15 at 17:22
  • @kritya That class in (old) version of stax api is only used if no real implementation found, so that is not the root cause. As to how an implementation is located, see http://docs.oracle.com/cd/E17802_01/webservices/webservices/docs/2.0/tutorial/doc/StAX4.html for official explanation, or http://stackoverflow.com/questions/17807123/how-to-override-a-service-provider-in-java or http://veithen.github.io/2013/10/02/broken-by-design-websphere-stax.html. – StaxMan Jul 13 '15 at 21:36
  • @kritya Someone else is having the same issue with `FactoryConfigurationError: Provider com.bea.xml.stream.MXParserFactory not found`, but when using pure Jackson on Android (http://stackoverflow.com/q/31360025/937715). I'd suggest following that issue, because I think this is the underlying issue. If we solve that, then all's left is to make sure POI works ok. – Sean Barbeau Jul 14 '15 at 13:32

5 Answers5

5

Check FAQ #18:

This error indicates that the class XMLEventFactory does not provide functionality which POI is depending upon. There can be a number of different reasons for this:

Outdated xml-apis.jar, stax-apis.jar or xercesImpl.jar:

  • These libraries were required with Java 5 and lower, but are not actually required with spec-compliant Java 6 implementations, so try removing those libraries from your classpath. If this is not possible, try upgrading to a newer version of those jar files.

...

You probably need to exclude the stax:stax-api dependency through the build system that you use. I just solved a similar problem (same stack trace but from Groovy) by applying this method.

UPDATE: It is best if you use the dependencies from a Maven repository, it will largely simplify your dependencies section:

dependencies {
    compile 'com.android.support:appcompat-v7:21.0.3'
    compile 'com.android.support:multidex:1.0.0'
    compile ('org.apache.poi:poi-ooxml:3.12') {
        exclude group: 'stax', module: 'stax-api'
    }
}

You can now also remove the extra libraries that you have under the libs directory.

The Apache POI FAQ answer indicates that stax may not be needed at all for some Java versions, especially above 6.

nekojsi
  • 1,423
  • 2
  • 13
  • 28
  • you mean I can exclude out the stax api and include its implementation only ? Note: I am using this on android. Sorry if you know this already but. Android doesn't have the Stack Api weather you run it on Java 5 or 6 – kritya Jun 23 '15 at 08:02
  • Check the update for the dependencies I am using in my gradle project. And can you please tell me which ones did you keep and which ones did you remove. Thanks – kritya Jun 23 '15 at 08:06
  • Yes, I did read the POI faq and especially that question. But I need to attach it as android deliberately doesn't include it the stream package. So I need to attach the extra jar's for that only. – kritya Jul 01 '15 at 16:47
  • the dependency snipit gives an error gradle dsl function exclude not found – kritya Jul 01 '15 at 16:48
  • Seems to be a problem with the syntax. Please check your script or update the question with the actual dependencies section you use. – nekojsi Jul 01 '15 at 20:42
  • Sorry for the late reply. I updated my question with the actual dependency. Thanks – kritya Jul 07 '15 at 17:30
  • You are using the `compile` method with a `files` parameter, not with maven-style coordinates. This way, I think you will have to have all the stax-related libraries removed (together with the `exclude`). Could you try that? Otherwise, I suggest for you to migrate to obtaining dependencies from maven repositories and not using local jars as libraries, so you don't have to care about transitive dependencies too much. – nekojsi Jul 07 '15 at 23:14
  • Well, I cant use the maven like dependency because I am using a modified version of poi jar's for making it compatible with android. how do I go about the first solution ? – kritya Jul 08 '15 at 06:53
  • If you don't need to use JAXB or have any other modification of POI's source, I suggest you just stick with the official jar release from a maven repository. And *only* exclude stax as specified in the answer. I believe that you will at least have a problem which is solvable more easily or resolve the issue altogether that way. You can just try building it with the dependencies provided in my answer (add any additional POI artifact if needed) and see the result. – nekojsi Jul 08 '15 at 08:05
  • Well, I don't know if I am right or not. But just what I think. POI must be using JAXB for XML parsing. and without JAXB it won't be possible. Well, XML parsing is at the bottom most layer and without it won't be possible to do anything like reading or writing. So how can I omit out JAXB from POI. Won't it make it useless ? Thanks for again helping this far. – kritya Jul 08 '15 at 08:51
  • That makes sense, together with Sean's answer and explanation. However, I can see that StaX has been implemented for Android, or at least that's what this issue says: https://code.google.com/p/android/issues/detail?id=1332. Otherwise, I cannot find any evidence online that JSR173 is excluded from Android, so I thought it's simplest if you just try. – nekojsi Jul 08 '15 at 09:25
  • I did give that solution a try too. But the only solution I can find there points me here https://code.google.com/p/dalvik/wiki/JavaxPackages which appears to be forbidden to me. Sorry if I missed something there. – kritya Jul 08 '15 at 18:02
  • Tried it myself now, and saw the problem completely. I posted the wrong answer in the first place, as the Groovy and Android scenarios are not comparable. – nekojsi Jul 09 '15 at 09:02
  • However, I can only suggest you, similarly as Sean, to try to modify Apache POI's source to not create an `XMLEventFactory` using JRE specifics like those providers, but to instantiate it differently in an Android-friendly way. – nekojsi Jul 09 '15 at 09:09
  • Any help on how to proceed with modifying the source of POI? I do have its source. Any small example or a link on how to do would be of good help. Thanks – kritya Jul 09 '15 at 16:09
  • 1
    What I meant was: your problem is coming from the line `final XMLEventFactory f = XMLEventFactory.newInstance();` in POI. Instead of calling `XMLEventFactory.newInstance()`, you can directly create the `XMLEventFactory` implementation via constructor from your stax dependency (class called `XMLEventFactoryImpl`, I guess). You should repeat this for every `XML***Factory.newInstance()` in POI's source, as obviously that factory method with dynamic locate does not work well on Android. – nekojsi Jul 10 '15 at 11:59
  • Well again sorry for the late reply. But I was trying to resolve this myself but couldn't. Yes I found where that error was occuring in the POI source. But I couldn't compile it in eclipse because it keeps on pointing errors at several java files. Any help? One more thing. Well think. I don't know if I am correct or not. But isn't the error being generated in the javax.xml. package ? So shouln't I change that instead of changing the poi? Like change the implementaion class import or something im the stax api itself? Wouldn't that be better and generic ? – kritya Jul 13 '15 at 08:28
  • Sorry, nothing further (I have never had any experience with compiling POI from source). Changing `javax.xml` seems to be forbidden in Android as the package is considered a system package. If you are creating a network app, I would only suggest to think about having a server-side solution like a REST service for converting/extracting the files. – nekojsi Jul 13 '15 at 11:56
  • Well, virtually we are not editing the javax.xml. package because it is attached as edu.csf. something at it is attached as a seperate jar. Which I think can be edited? Can't I? – kritya Jul 13 '15 at 15:15
  • Yes, you obviously can, but it seems that stax is relying on yet another library which is missing from Android, and I think it is simpler to edit POI than to edit stax. – nekojsi Jul 13 '15 at 19:30
4

Add the following to your gradle file:

implementation 'com.fasterxml:aalto-xml:1.0.0'

And relax...

Stephen Rauch
  • 47,830
  • 31
  • 106
  • 135
3

Try using the pre-packaged JARs from the CUTR Maven repo for stax and Aalto:

apply plugin: 'com.android.application'

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 21
    buildToolsVersion "21.1.2"

    packagingOptions{
        // exclude 'META-INF/DEPENDENCIES'  <--- and try commenting this out, I don't believe it should be needed
        exclude 'META-INF/NOTICE'
        exclude 'META-INF/NOTICE.txt'
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/LICENSE.txt'
        pickFirst 'META-INF/services/javax.xml.stream.XMLInputFactory'
    }

    defaultConfig {
        applicationId "com.quizwiz.sharmakritya.poi"
        minSdkVersion 16
        targetSdkVersion 21
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}
dependencies {
    compile 'com.android.support:appcompat-v7:21.0.3'
    compile files('libs/poi-3.12-20150511.jar')
    compile files('libs/poi-ooxml-3.12-20150511.jar')
    compile files('libs/poi-ooxml-schemas-3.12-20150511.jar'){
    compile files('libs/xmlbeans-2.6.0.jar')
    // JSR173 APIs
    compile 'edu.usf.cutr.android.xml:stax2-api-android:3.1.1'
    compile 'edu.usf.cutr.android.xml:stax-api-android:1.0-2'
    // JSR173 provider implementation - Aalto
    compile 'edu.usf.cutr.android.xml:aalto-xml-android:0.9.8'
}

I believe the main issue here is that Apache POI depends on JSR173 Streaming API for XML, which depends on the platform (in our case Android) being able to provide an implementation and underlying XML parsing provider. Android doesn't support JSR173, so it can't find a provider - com.bea.xml.stream.EventFactory is the default provider, and it can't even find that one (see JAXB marshalling exception javax.xml.stream.FactoryConfigurationError running with Java 5 for more details on this topic).

Aalto is an open-source JSR173 provider, so you should be able to use this in place of the BEA implementation (com.bea.xml.stream.EventFactory). The Aalto archive (JAR file) includes the necessary registration (under META-INF/services/javax.xml.stream.XMLInputFactory file, that points to the Aalto class com.fasterxml.aalto.stax.InputFactoryImpl) that should allow a Java platform to recognize it as a JSR173 implementation. As a result, you should no longer get the edu.usf.cutr.javax.xml.stream.FactoryConfigurationError: Provider com.bea.xml.stream.EventFactory not found error, because Android should recognize that Aalto is an available provider, and use Aalto instead.

Note - apparently there are bugs with previous versions of ADT for Eclipse and Gradle plugin < 0.7.0 that strips the /META-INF/* files 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.

If the above doesn't work, 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 (javax.xml.stream.XMLInputFactory) into /resources/META-INF/services.

If the above doesn't work, I also noticed that you have a exclude 'META-INF/DEPENDENCIES' in your packagingOptions - I'd remove this, as I don't believe you should need that line, and it may be causing problems with registering Aalto as well.

You could also check out some other solutions/work that people have done trying to get Apache POI working on Android:

Community
  • 1
  • 1
Sean Barbeau
  • 11,496
  • 8
  • 58
  • 111
  • Sorry, maybe I don't get what I should exactly do. Because I don't know how to repackage the FasterXML in the required form. I tried adding the alto-xml-jar-0.9.6.jar from woodstox website. And it still says implementation not found. So can you please help me on what I need to do – kritya Jul 01 '15 at 16:43
  • Sorry, I wasn't clear. I just changed the answer above - you'd need to process the aalto-xml JAR file to change the namespace, just like you did with the stax JARs, and add it to your dependencies. I was hoping that aalto would register itself, but now I'm realizing that you're not using Jackson, and all parsing happens within Apache POI library. So, I'm not sure if it will work (because Apache POI doesn't necessarily know about Aalto being packaged with the app). But, its worth a try. – Sean Barbeau Jul 01 '15 at 16:52
  • I tried repackaging the aalto-xml the way you said. Still gives the same error of Provider not found. The error is generated in the javax.xml.stream.* and not in the POI. So I guess error must not lie at POI end or should not depend on it. Also, sorry if I sound stupid. But the alto-xml doesn't contain any package as com.bea.* that is actually needed by the stax api. Correct me if it doesn't work this way. Thanks – kritya Jul 01 '15 at 17:37
  • Yeah, I was afraid of that. POI is simply using the JSR173 API internally, which assumes that the platform (in your case Android) has a registered JSR173 provider. But, Android doesn't know about Aalto, because its bundled with your app. You'd need to find a way to register Aalto with the JSR173 implementation that POI is calling - seems like the easiest way to do this is to modify Apache POI? I'll update my answer saying this - also, I found a few links that might help you, as it appears others have gotten portions of POI to work on Android. – Sean Barbeau Jul 01 '15 at 18:35
  • Sorry for the late reply. The 2nd option don't really solve my problem any closely and I have explored on 100's of such option. But, can you help me a bit more over the 1st option as on how to proceed or anything. Thanks – kritya Jul 07 '15 at 17:27
  • @SeanBareau Well The first solution gives me the error dump same as the 2nd one I gave in the question that is can't make multidex application. I am totally unaware the reason of this from the starting. The second solution gives me error while compiling the application. Ill update my question with that. Thanks – kritya Jul 13 '15 at 20:25
  • @SeanBareau Is there someway of achieving this ? Why can't I edit the Stax API jar ? (most probs from the source of it) and change the import of the come.bea. something to the aalto stuff. I don't know how far this is possible. But can't there be a similar work around of editing the Stax API jar itself to make it point to the Aalto implementation instead of forcing it using the META-INF/services or somehow create an illusion for android the way we are doing for javax.xml. (sorry for using such lay man like language but I think it is the best way to explain my self) Correct me if I am wrong. – kritya Jul 13 '15 at 20:37
  • or using this maybe http://developer.android.com/reference/java/util/ServiceLoader.html – kritya Jul 13 '15 at 20:43
  • Ok, I think you're getting closer with the packaging error. I just edited my answer to include a new "pickFirst 'META-INF/services/javax.xml.stream.XMLInputFactory'" property in packagingOptions. Can you try this and let me know if it works? – Sean Barbeau Jul 13 '15 at 20:48
  • Can you try removing the workaround where you add the file manually, and then try again (keeping the `pickFirst ` settings)? – Sean Barbeau Jul 13 '15 at 20:56
  • 1
    Ok, so this bug may be affecting "pickFirst" - https://code.google.com/p/android/issues/detail?id=158630. Can you 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 might be fixed in 1.3 RC1 - http://tools.android.com/download/studio/canary/latest. – Sean Barbeau Jul 13 '15 at 21:18
  • And try removing the multi-dex stuff, as well. – Sean Barbeau Jul 13 '15 at 21:32
  • Well, packaging error was resolved by removing the intermediates directory that was the cause of conflict. But even after upgrading the Android Studio and gradle, still gives me the multi-dex instantiation error. – kritya Jul 14 '15 at 07:18
  • On finding something over the problem, I think the exception is actually thrown because of this: Thrown when the VM notices that a program tries to reference, on a class or object, a field that does not exist. http://developer.android.com/reference/java/lang/NoSuchFieldException.html – kritya Jul 14 '15 at 07:26
  • Do you still get the multi-dex error when removing all multi-dex references from build.gradle, and removing the BEA library? If so, then you'll need to figure out a way to get multi-dex working with POI - that I'm afraid I'm not going to be much help on. – Sean Barbeau Jul 14 '15 at 13:29
  • I am following that question. Maybe it is just an indication it is not a problem of POI. Maybe its something changed in android since you made those tools. Thanks a lot. And what I think, the multi-dex is cause by Aalto because remove it doesn't at least gives that error and all the DEX files are extracted correctly. But after putting Aalto the DEX can't be extracted successfully. The link to exception I gave in my last comment sought of confirm that. At least to me. Again I am not sure if I am correct or not. Thanks a lot. – kritya Jul 15 '15 at 16:27
1

After upgrading POI from 3.9 to 3.15 we were getting a:

javax.xml.stream.FactoryConfigurationError: Provider for class javax.xml.stream.XMLEventFactory cannot be created

Besides POI, our build included:

compile ('com.msopentech.odatajclient:odatajclient-engine:0.9.0')

it turned out that the odatajclient jar included a java.xml.stream.XMLEventFactory file in its META-INF\services, the contain of that file was com.fasterxml.aalto.stax.EventFactoryImpl but the aalto included in odatajclient was old and com.fasterxml.aalto.stax.EventFactoryImpl was finally inheriting from com.msopentech.javax.xml.stream.XMLEventFactory instead of java.xml.stream.XMLEventFactory class.

At run time POI was using the java.xml.stream.XMLEventFactory, the class loader returned com.fasterxml.aalto.stax.EventFactoryImpl and the cast to java.xml.stream.XMLEventFactory failed.

The solution was excluding the module that included the old aalto:

compile ('com.msopentech.odatajclient:odatajclient-engine:0.9.0')
{
   exclude group: 'com.msopentech.odatajclient', module: 'odatajclient-engine-xml'
}
Sebastian
  • 11
  • 1
  • Thanks for answering, have you tested this ? If yes, on which Android API? – kritya Nov 14 '16 at 15:12
  • Yes, I have tested it. I was able to run from Eclipse but not from the jar file generated by Gradle. Once we removed the dependency in the build.gradle we have been able to run from the jar file. – Sebastian Nov 14 '16 at 17:39
  • I am not running on Android, I am running on PC, Java 1.8. I wanted to point out that it was a `XMLEventFactory` dependency at run time the cause of the problem. – Sebastian Nov 14 '16 at 17:42
0

for me adding

implementation  'com.android.support:multidex:1.0.0',
implementation  'com.fasterxml:aalto-xml:1.0.0'

and

multiDexEnabled true in defaultConfig

solve the problem