为了让Apache POI在Android上运行,我需要让Stack在Android上运行。关注这个问题:Using JAXB with Google Android和@Sean Barbeau的回答。我成功地将所有jar转换为Android兼容的,包括Apache POI库,但它仍然给我这个运行时错误:
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)
整个错误的关键是android缺少包com.bea.xml.stream
。我该如何解决这个问题?
我试着通过从here下载外部jar来自行解决这个问题。但这给了我奇怪的错误:
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)
注意:从Gradle Dependencies中删除com.bea.stax.impl_1.2.0.jar会让我回到第一个错误。
请帮我找一个在android上使用com.bea.xml.stream包的方法。 UPDATE
在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编译时出错:
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
检查FAQ #18:
此错误表示类XMLEventFactory未提供POI所依赖的功能。这可能有很多不同的原因:
过时的xml-apis.jar,stax-apis.jar或xercesImpl.jar:
- Java 5及更低版本需要这些库,但实际上并不需要符合规范的Java 6实现,因此请尝试从类路径中删除这些库。如果无法做到这一点,请尝试升级到这些jar文件的较新版本。
...
您可能需要通过您使用的构建系统排除stax:stax-api
依赖项。我通过应用此方法解决了类似的问题(相同的堆栈跟踪,但来自Groovy)。
更新:最好是使用Maven存储库中的依赖项,它将在很大程度上简化您的依赖项部分:
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'
}
}
您现在还可以删除libs
目录下的额外库。
Apache POI FAQ答案表明某些Java版本可能根本不需要stax,尤其是6以上版本。
尝试使用来自CUTR Maven repo的预打包JAR进行stax和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'
}
我认为这里的主要问题是Apache POI依赖于JSR173 Streaming API for XML,它依赖于平台(在我们的例子中是Android)能够提供实现和底层XML解析提供程序。 Android不支持JSR173,因此无法找到提供者 - com.bea.xml.stream.EventFactory
是默认提供者,甚至找不到它(有关此主题的更多详细信息,请参阅JAXB marshalling exception javax.xml.stream.FactoryConfigurationError running with Java 5)。
Aalto是一个开源的JSR173提供程序,因此您应该能够使用它来代替BEA实现(com.bea.xml.stream.EventFactory
)。 Aalto存档(JAR文件)包括必要的注册(在META-INF/services/javax.xml.stream.XMLInputFactory
文件下,指向Aalto类com.fasterxml.aalto.stax.InputFactoryImpl
),它应该允许Java平台将其识别为JSR173实现。因此,您不应再收到edu.usf.cutr.javax.xml.stream.FactoryConfigurationError: Provider com.bea.xml.stream.EventFactory not found
错误,因为Android应该认识到Aalto是可用的提供程序,而是使用Aalto。
注意 - 显然there are bugs与早期版本的ADT for Eclipse和Gradle插件<0.7.0在构建过程中从JAR中剥离/META-INF/*
文件。似乎> = v0.7.0应该没有问题根据谷歌,但从其他人的报告听起来它仍然可能有问题,并可能删除META-INF/services/javax.xml.stream.XMLInputFactory
文件,这是平台注册阿尔托所需的。
如果上述方法无效,请尝试AOSP issue 59658 comment 22中提到的解决方法:
- 右键单击/ src / main(你有/ java和/ res文件夹),
- 选择新建>文件夹> Java资源文件夹,
- 单击完成(不要更改文件夹位置),
- 右键单击new / resources文件夹,
- 选择新建>目录
- 输入“META-INF”(不带引号),
- 右键单击
/resources/META-INF
文件夹,- 选择新建>目录
- 输入“服务”(不含引号)
- 将您需要的任何文件复制到
/resources/META-INF/services
对于你,在上面的步骤10中,你需要将this file (javax.xml.stream.XMLInputFactory)复制到/resources/META-INF/services
。
如果上述方法不起作用,我也注意到你的包装中有一个exclude 'META-INF/DEPENDENCIES'
Options - 我会删除它,因为我不相信你应该需要那条线,这也可能导致注册Aalto的问题。
您还可以查看其他人尝试让Apache POI在Android上运行的解决方案/工作:
将以下内容添加到gradle文件中:
implementation 'com.fasterxml:aalto-xml:1.0.0'
放松一下......
将POI从3.9升级到3.15之后我们得到了:
javax.xml.stream.FactoryConfigurationError: Provider for class javax.xml.stream.XMLEventFactory cannot be created
除了POI,我们的构建还包括:
compile ('com.msopentech.odatajclient:odatajclient-engine:0.9.0')
事实证明,odatajclient jar在其java.xml.stream.XMLEventFactory
中包含一个META-INF\services
文件,该文件的包含是com.fasterxml.aalto.stax.EventFactoryImpl
但odatajclient中包含的aalto是旧的,com.fasterxml.aalto.stax.EventFactoryImpl
最终继承自com.msopentech.javax.xml.stream.XMLEventFactory
而不是java.xml.stream.XMLEventFactory
类。
在运行时POI使用java.xml.stream.XMLEventFactory
,类加载器返回com.fasterxml.aalto.stax.EventFactoryImpl
并且演员到java.xml.stream.XMLEventFactory
失败。
解决方案是排除包含旧aalto的模块:
compile ('com.msopentech.odatajclient:odatajclient-engine:0.9.0')
{
exclude group: 'com.msopentech.odatajclient', module: 'odatajclient-engine-xml'
}
对我来说
implementation 'com.android.support:multidex:1.0.0',
implementation 'com.fasterxml:aalto-xml:1.0.0'
和
defaultConfig中的multiDexEnabled true
解决这个问题