Android Docx4J 在 MS Word 文件中读取时出错:在路径上找不到类 org.eclipse.persistence.oxm.NamespacePrefixMapper



我正在尝试使用Docx4j库来读取用户选择的Word文件的内容(尝试按照 https://github.com/plutext/Docx4j4Android4 中的代码进行操作(但是,当我在MS Word文件中读取时,我收到以下错误:

W/System.err: log4j:ERROR Could not parse url [jar:file:/data/app/com.example.diffcheckertest-8hLouozp5QPE6U8NaxyKYA==/base.apk!/log4j.xml].
javax.xml.parsers.ParserConfigurationException: No validating DocumentBuilder implementation available
at org.apache.harmony.xml.parsers.DocumentBuilderFactoryImpl.newDocumentBuilder(DocumentBuilderFactoryImpl.java:61)
...
Process 20716 terminated.
Caused by: java.lang.ClassNotFoundException: Didn't find class "org.eclipse.persistence.oxm.NamespacePrefixMapper" on path: DexPathList[[zip file "/data/app/com.example.diffcheckertest-8hLouozp5QPE6U8NaxyKYA==/base.apk"]

下面是我打开MS Word文档和发生错误的MainActivity.kt代码行(我已经导入了必要的实用程序(:

import android.app.Activity
import android.content.Intent
import android.os.Bundle
import android.view.View
import android.widget.Button
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import org.apache.commons.lang3.StringUtils;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart;
import java.io.BufferedReader
import java.io.InputStreamReader
class MainActivity : AppCompatActivity() {
private var READ_IN_FILE:Int = 2; // Request code used when reading in a file

// Asks a user to read in a file
private fun chooseFile(view: View) {
// Only the below specified mime types are allowed in the picker
var selectFile = Intent(Intent.ACTION_GET_CONTENT)
selectFile.type = "*/*"
selectFile = Intent.createChooser(selectFile, "Choose a file")
startActivityForResult(selectFile, READ_IN_FILE)
}
// After receiving a result for a launched activity...
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == READ_IN_FILE) { // When a result has been received, check if it is the result for READ_IN_FILE
if (resultCode == Activity.RESULT_OK) { // heck if the operation to retrieve the Activity's result is successful
// Attempt to retrieve the file
try {
var uri = data?.data // Retrieve the file's resource locator
var document = WordprocessingMLPackage.load(uri?.let { contentResolver.openInputStream(it) });
//var documentPart: MainDocumentPart = document.getMainDocumentPart();
Toast.makeText(this, "DiffChecker successfully read in the file :D", Toast.LENGTH_SHORT).show()
} catch (e: Exception) { // If the app failed to attempt to retrieve the error file, throw an error alert
println("Exception: " + e.toString());
Toast.makeText(this, "Sorry, but there was an error reading in the file", Toast.LENGTH_SHORT).show()
}
}
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
findViewById<Button>(R.id.file1).setOnClickListener(::chooseFile);
}
}

以下是我的build.gradle代码(应用程序级别(:

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 29
buildToolsVersion "29.0.2"
defaultConfig {
applicationId "com.example.diffcheckertest"
minSdkVersion 22
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
packagingOptions {
exclude 'META-INF/DEPENDENCIES'
exclude 'META-INF/LICENSE'
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/license.txt'
exclude 'META-INF/NOTICE'
exclude 'META-INF/NOTICE.txt'
exclude 'META-INF/notice.txt'
exclude 'META-INF/ASL2.0'
exclude("META-INF/*.kotlin_module")
}
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.core:core-ktx:1.2.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
implementation files('libs/activation.jar')
implementation files('libs/additionnal.jar')
implementation files('libs/awt-bastardised-17v8.jar')
implementation files('libs/istack-commons-runtime-3.0.4-SNAPSHOT.jar')
implementation files('libs/jaxb-core-2.3.0-SNAPSHOT-ANDROID.jar')
implementation files('libs/jaxb-runtime-2.3.0-SNAPSHOT-ANDROID.jar')
//implementation files('libs/commons-lang3-3.7.jar')
//implementation files('libs/commons-text-1.2.jar')
implementation 'javax.xml.stream:stax-api:1.0-2'
implementation 'com.fasterxml:aalto-xml:1.0.0'
implementation files('libs/docx4j-6.1.1-SNAPSHOT-shaded.jar')
}

构建是我的build.gradle代码(项目级(:

// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = '1.3.61'
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}

如果没有javax.xml.bind:jaxb-api:2.2.12依赖关系,你的项目是如何工作的?它应该首先抛出java.lang.NoClassDefFoundError: Failed resolution of: Ljavax/xml/bind/JAXBContext;

Android 不支持开箱即用的 JAXB,您必须显式添加依赖项。

implementation 'javax.xml.bind:jaxb-api:2.2.12'

我没有尝试您的 gradle 设置,而是决定创建一个新项目并从头开始。幸运的是,我可以毫无问题地运行和加载任何 docx 文件。

请下载我的示例存储库并在您的系统中试用。

自 Android 4.4(API 级别 19(起提供 SAF(存储访问框架(选择文件:

// Asks a user to read in a file
private fun chooseFile(view: View) {
// Only the below specified mime types are allowed in the picker
var selectFile = Intent(Intent.ACTION_OPEN_DOCUMENT)
selectFile.type = "*/*"
selectFile.addCategory(Intent.CATEGORY_OPENABLE)
selectFile = Intent.createChooser(selectFile, "Choose a file")
startActivityForResult(selectFile, READ_IN_FILE)
}

防止ClassNotFoundException"org.eclipse.persistence.oxm.NamespacePrefixMapper"将以下行添加到您的 gradle 文件依赖项中:

implementation 'org.eclipse.persistence:eclipselink:2.7.6'

为了防止重复类错误,您可以排除重复类:

implementation ('org.eclipse.persistence:eclipselink:2.7.6'){
exclude group: 'javax.persistence.spi', module: 'ProviderUtil'
exclude group: 'javax.persistence', module: 'Access'
}

如何在安卓中运行 JAXB

最新更新