使用 javafx 和 apache POI 的项目在 dex 期间出错

Getting error during dex with a project using javafx and apache POI

我正在尝试在 Android 上使用 Apache POI 为此,我在 eclipse 上创建了一个 gradle 项目,但是当我执行 gradle 任务 androidInstall 时,我得到了一个dex 步骤期间出错。 (运行 任务正在运行)

此处错误:

Uncaught translation error: java.lang.IllegalArgumentException: already added: Ljavax/xml/stream/EventFilter;
Uncaught translation error: java.lang.IllegalArgumentException: already added: Ljavax/xml/stream/FactoryConfigurationError;
Uncaught translation error: java.lang.IllegalArgumentException: already added: Ljavax/xml/stream/FactoryFinder;
Uncaught translation error: java.lang.IllegalArgumentException: already added: Ljavax/xml/stream/FactoryFinder;
Uncaught translation error: java.lang.IllegalArgumentException: already added: Ljavax/xml/stream/FactoryFinder$ClassLoaderFinder;
Uncaught translation error: java.lang.IllegalArgumentException: already added: Ljavax/xml/stream/FactoryFinder$ClassLoaderFinderConcrete;
Uncaught translation error: java.lang.IllegalArgumentException: already added: Ljavax/xml/stream/Location;
Uncaught translation error: java.lang.IllegalArgumentException: already added: Ljavax/xml/stream/StreamFilter;
Uncaught translation error: java.lang.IllegalArgumentException: already added: Ljavax/xml/stream/XMLEventFactory;

UNEXPECTED TOP-LEVEL EXCEPTION:
java.lang.RuntimeException: Translation has been interrupted
at com.android.dx.command.dexer.Main.processAllFiles(Main.java:613)
at com.android.dx.command.dexer.Main.runMultiDex(Main.java:366)
at com.android.dx.command.dexer.Main.run(Main.java:275)
at com.android.dx.command.dexer.Main.main(Main.java:245)
at com.android.dx.command.Main.main(Main.java:106)
Caused by: java.lang.InterruptedException: Too many errors
at com.android.dx.command.dexer.Main.processAllFiles(Main.java:605)
... 4 more
16:41:25.082 [ERROR] [org.gradle.api.internal.project.ant.AntLoggingAdapter] [ant:java] Java Result: 2
16:41:25.083 [DEBUG] [org.gradle.api.internal.project.ant.AntLoggingAdapter] Setting project property: dexResult -> 2
16:41:25.084 [DEBUG] [org.gradle.api.Project] Dex result value = 2
16:41:25.093 [DEBUG] [org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter] Finished executing task ':dex'
16:41:25.094 [LIFECYCLE] [class org.gradle.TaskExecutionLogger] :dex FAILED
16:41:25.095 [INFO] [org.gradle.execution.taskgraph.AbstractTaskPlanExecutor] :dex (Thread[Daemon worker Thread 2,5,main]) completed. Took 2 mins 19.455 secs.
16:41:25.095 [DEBUG] [org.gradle.execution.taskgraph.AbstractTaskPlanExecutor] Task worker [Thread[Daemon worker Thread 2,5,main]] finished, busy: 21 mins 29.722 secs, idle: 0.053 secs
16:41:25.103 [ERROR] [org.gradle.BuildExceptionReporter] 
16:41:25.108 [ERROR] [org.gradle.BuildExceptionReporter] FAILURE: Build failed with an exception.
16:41:25.109 [ERROR] [org.gradle.BuildExceptionReporter] 
16:41:25.109 [ERROR] [org.gradle.BuildExceptionReporter] * What went wrong:
16:41:25.109 [ERROR] [org.gradle.BuildExceptionReporter] Execution failed for task ':dex'.
16:41:25.110 [ERROR] [org.gradle.BuildExceptionReporter] > warning: Ignoring InnerClasses attribute for an anonymous inner class
16:41:25.110 [ERROR] [org.gradle.BuildExceptionReporter]   (org.apache.xmlbeans.XmlBeans) that doesn't come with an
16:41:25.111 [ERROR] [org.gradle.BuildExceptionReporter]   associated EnclosingMethod attribute. This class was probably produced by a
16:41:25.111 [ERROR] [org.gradle.BuildExceptionReporter]   compiler that did not target the modern .class file format. The recommended
16:41:25.112 [ERROR] [org.gradle.BuildExceptionReporter]   solution is to recompile the class from source, using an up-to-date compiler
16:41:25.112 [ERROR] [org.gradle.BuildExceptionReporter]   and without specifying any "-target" type options. The consequence of ignoring
16:41:25.112 [ERROR] [org.gradle.BuildExceptionReporter]   this warning is that reflective operations on this class will incorrectly
16:41:25.115 [ERROR] [org.gradle.BuildExceptionReporter]   indicate that it is *not* an inner class.
16:41:25.115 [ERROR] [org.gradle.BuildExceptionReporter]   warning: Ignoring InnerClasses attribute for an anonymous inner class
16:41:25.116 [ERROR] [org.gradle.BuildExceptionReporter]   (org.apache.xmlbeans.XmlSimpleList) that doesn't come with an
16:41:25.140 [ERROR] [org.gradle.BuildExceptionReporter]   associated EnclosingMethod attribute. This class was probably produced by a
16:41:25.140 [ERROR] [org.gradle.BuildExceptionReporter]   compiler that did not target the modern .class file format. The recommended
16:41:25.140 [ERROR] [org.gradle.BuildExceptionReporter]   solution is to recompile the class from source, using an up-to-date compiler
16:41:25.141 [ERROR] [org.gradle.BuildExceptionReporter]   and without specifying any "-target" type options. The consequence of ignoring
16:41:25.141 [ERROR] [org.gradle.BuildExceptionReporter]   this warning is that reflective operations on this class will incorrectly
16:41:25.141 [ERROR] [org.gradle.BuildExceptionReporter]   indicate that it is *not* an inner class.
16:41:25.141 [ERROR] [org.gradle.BuildExceptionReporter]   warning: Ignoring InnerClasses attribute for an anonymous inner class
16:41:25.142 [ERROR] [org.gradle.BuildExceptionReporter]   (org.apache.xmlbeans.XmlSimpleList) that doesn't come with an
16:41:25.142 [ERROR] [org.gradle.BuildExceptionReporter]   associated EnclosingMethod attribute. This class was probably produced by a
16:41:25.142 [ERROR] [org.gradle.BuildExceptionReporter]   compiler that did not target the modern .class file format. The recommended
16:41:25.142 [ERROR] [org.gradle.BuildExceptionReporter]   solution is to recompile the class from source, using an up-to-date compiler
16:41:25.143 [ERROR] [org.gradle.BuildExceptionReporter]   and without specifying any "-target" type options. The consequence of ignoring
16:41:25.143 [ERROR] [org.gradle.BuildExceptionReporter]   this warning is that reflective operations on this class will incorrectly
16:41:25.143 [ERROR] [org.gradle.BuildExceptionReporter]   indicate that it is *not* an inner class.
...

我读到我需要添加这个来忽略警告但是我在 compileSdkVersion

上收到另一个错误
lintOptions {
    abortOnError false
}

这是我的 build.gradle 文件:

buildscript {
    repositories {
        jcenter()
    }

    dependencies {
        classpath 'org.javafxports:jfxmobile-plugin:1.0.0-b8'
    }
}

apply plugin: 'org.javafxports.jfxmobile'

mainClassName = "JavaFXStage"
version = '1.0'

repositories {
    jcenter()
}

jfxmobile {
    ios {
        forceLinkClasses = ['ensemble.**.*']
    }

    android {

        javafxportsVersion = '8u40-b5'
        compileSdkVersion  = 23     
        applicationPackage = 'any.package.name' 

    }
}

dependencies{
    def poiVersion = "3.10.1"
    compile "org.apache.poi:poi:${poiVersion}"
    compile "org.apache.poi:poi-ooxml:${poiVersion}"
    compile "org.apache.poi:ooxml-schemas:1.1"
    compile "org.apache.xmlbeans:xmlbeans:2.6.0"
}

如果您需要有关该项目的更多信息,请随时询问。

如果您有任何解决我问题的提示,谢谢。

托马斯

由于一些限制,在 Android 上使用 Apache POI 无法开箱即用。其中之一是 xmlbeans jar 多次包含一些 类,这使 Android 编译器感到困惑。还有关于 pacakge javax 代码和代码大小的问题。

目前有两个项目试图解决这个问题:

两者都试图通过将 类 重新打包成一个更紧凑的 jar 文件来解决这个问题,然后可以将其添加到 Android 应用程序中。 Android5xlsx 目前基于 POI 3.12,poi-on-android 基于 3.15-beta1,可以很容易地根据最新版本的 POI 重新构建。

我通过排除 gradle.build:

中的 xmlbeans 解决了 Dex 步骤中的错误
compile 'org.apache.poi:poi:3.16'
compile ('org.apache.poi:poi-ooxml:3.16') {
    exclude group: 'org.apache.xmlbeans', module: 'xmlbeans'
}

在我的 java 代码中,我没有使用 xmlbeans,而是使用了其他解析器。这是我的进口清单:

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.DocumentBuilder;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import org.w3c.dom.Node;
import org.w3c.dom.Element;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;