Android Docx4J Ошибка при чтении в файле MS Word: не найден класс org.eclipse.persistence.oxm.NamespacePrefixMapper по пути - PullRequest
0 голосов
/ 14 февраля 2020

Я пытаюсь использовать библиотеку 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"]

Ниже приведена строка кода в MainActivity.kt, где я открываю документ MS Word и где происходит ошибка (я импортировал файл необходимые утилиты):

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
}

Ответы [ 2 ]

1 голос
/ 20 февраля 2020

Как ваш проект работал без 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.

Пожалуйста, скачайте мой репозиторий образцов и попробуйте в вашей системе.

0 голосов
/ 17 февраля 2020

Выбор файла с использованием SAF (Storage Access Framework) доступен начиная с Android 4.4 (уровень API 19):

// 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 в Android

...