Pax Exam issue with Apache POI wrapped bundle

不想你离开。 提交于 2020-01-03 04:26:04

问题


I have been beating my head against the wall trying to get Apache POI to work within an OSGi bundle. Here is the history of what I have tried with no luck:

1) I initially tried using the pre wrapped Apache Servicemix POI bundle. However this had many dependencies I had to deploy, many of which were not needed. I hit a wall as even after adding Apache POI servicemix (and its dependencies), i was still getting issues with missing classes.

2) Due to the amount of unneeded stuff in the first solution, I decided to wrap up the dependencies inside a bundle. Basically I have a Blueprint service that acts as a wrapper for the POI functionality. All unit tests work fine but my pax exam tests were failing.

At first, it couldn't find classes that were dependencies (commons-codec,xmlbeans, etc). So I added the POI and POI OOMXL dependencies and all the other dependencies it needed. This solved most of the class loader issues. However this is the one I am currently stuck on. The bundle starts just fine, but once it hits a point where it tries create an excel workbook, it fails with the following stack trace:

java.lang.ClassNotFoundException: com.bea.xml.stream.EventFactory not found by org.ops4j.pax.exam.rbc [104]

at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1574)
at org.apache.felix.framework.BundleWiringImpl.access$400(BundleWiringImpl.java:79)
at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:2018)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at javax.xml.stream.FactoryFinder.newInstance(FactoryFinder.java:68)
at javax.xml.stream.FactoryFinder.find(FactoryFinder.java:178)
at javax.xml.stream.FactoryFinder.find(FactoryFinder.java:92)
at javax.xml.stream.XMLEventFactory.newInstance(XMLEventFactory.java:30)

Here are the dependencies I am including:

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>${apache.poi.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>${apache.poi.version}</version>
        </dependency>
        <dependency>
            <groupId>commons-codec</groupId>
            <artifactId>commons-codec</artifactId>
            <version>1.9</version>
        </dependency>
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <dependency>
            <groupId>org.apache.xmlbeans</groupId>
            <artifactId>xmlbeans</artifactId>
            <version>2.6.0</version>
        </dependency>

It seems that the pax container cannot find the EventFactory. If anyone has any suggestions i would greatly appreciate the help.


回答1:


Here is pom.xml for a working POI osgi bundle which is used to create XLSX exports. Maybe some exotic feature not 100% percent supported because of optional import, but it works for standard exports.

The apache commons bundles are osgi compliant, so if you are using with these dependencies it have to work (some of commons is used by other features, so not all is required). The features is in our karaf feature file, but you can use the bundles from the given maven origin in any OSGi container.

<feature name="stax" version="2.4.0">
    <bundle>mvn:org.apache.servicemix.specs/org.apache.servicemix.specs.stax-api-1.0/2.4.0</bundle>
    <bundle>mvn:org.apache.servicemix.specs/org.apache.servicemix.specs.jaxb-api-2.2/2.4.0</bundle>
</feature>  

<feature name="repo-apache-commons" version="1.0.0">
    <bundle>mvn:commons-beanutils/commons-beanutils/1.9.2</bundle>
    <bundle>mvn:commons-collections/commons-collections/3.2.1</bundle>
    <bundle>mvn:commons-io/commons-io/2.4</bundle>
    <bundle>mvn:org.apache.commons/commons-pool2/2.4.2</bundle>
    <bundle>mvn:org.apache.commons/commons-dbcp2/2.1.1</bundle>
    <bundle>mvn:commons-codec/commons-codec/1.9</bundle>
</feature>

<feature name="repo-bouncycastle" version="1.46">
    <bundle>mvn:org.bouncycastle/bcprov-jdk16/1.46</bundle>
    <bundle>mvn:org.bouncycastle/bcmail-jdk16/1.46</bundle>
    <bundle>mvn:org.bouncycastle/bctsp-jdk16/1.46</bundle>
</feature> 

POM.XML:

<?xml version="1.0" encoding="ISO-8859-1"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<version>3.13.1</version>

<properties>
    <poi.version>3.13</poi.version>
    <poi.schema.version>1.1</poi.schema.version>
    <poi.security.version>1.0</poi.security.version>
</properties>

<groupId>org.yourgroupid</groupId>
<artifactId>osgi-apache-poi</artifactId>
<packaging>bundle</packaging>
<name>osgi-apache-poi</name>
<description>Apache poi framework</description>

<build>
<plugins>

    <plugin>
    <groupId>org.apache.felix</groupId>
    <artifactId>maven-bundle-plugin</artifactId>
    <extensions>true</extensions>
    <configuration>
        <instructions>
                    <_exportcontents>
                        org.apache.poi.*;version=${poi.version},
                        org.openxmlformats.schemas.*;version=${poi.schema.version},
                        schemasMicrosoftComOfficeExcel.*;version=${poi.schema.version},
                        schemasMicrosoftComOfficeOffice.*;version=${poi.schema.version},
                        schemasMicrosoftComOfficePowerpoint.*;version=${poi.schema.version},
                        schemasMicrosoftComVml.*;version=${poi.schema.version},
                        org.etsi.uri.*;version=${poi.security.version}
                    </_exportcontents>
                    <Import-Package>
                        com.sun.javadoc;resolution:=optional,
                        com.sun.tools.javadoc;resolution:=optional,
                        org.apache.crimson.jaxp;resolution:=optional,
                        org.apache.tools.ant;resolution:=optional,
                        org.apache.tools.ant.taskdefs;resolution:=optional,
                        org.apache.tools.ant.types;resolution:=optional,
                        junit.framework.*;resolution:=optional,
                        junit.textui.*;resolution:=optional,
                        org.junit.*;resolution:=optional,
                        org.apache.xml.security.*;resolution:=optional,
                        org.apache.jcp.xml.dsig.internal.dom.*;resolution:=optional,
                        *
                    </Import-Package>
                    <DynamicImport-Package>
                        org.apache.xmlbeans.*,
                        schemaorg_apache_xmlbeans.*
                    </DynamicImport-Package>

        <!-- bundle supplied resource prefixes -->
        <Include-Resource>{maven-resources}</Include-Resource>

        <!-- Do not inline jars, include as jar files -->
        <!-- There are config files with same name will be overwritten -->
        <Embed-Dependency>*;scope=compile;inline=false</Embed-Dependency>


        </instructions>
    </configuration>
    </plugin>
</plugins>
</build>
<dependencies>
    <!-- Embedded dependencies -->
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi</artifactId>
        <version>${poi.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml-schemas</artifactId>
        <version>${poi.version}</version>
    </dependency>

    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>${poi.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-scratchpad</artifactId>
        <version>${poi.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>ooxml-schemas</artifactId>
        <version>${poi.schema.version}</version>
    </dependency>
    <dependency>
       <groupId>org.apache.poi</groupId>
       <artifactId>ooxml-security</artifactId>
       <version>${poi.security.version}</version>
    </dependency>
</dependencies>




回答2:


In addition to the above answer I also figured out my problem. Rather than running the unit test to debug, I started the karaf instance pax created. There was more tidbits in the logs that pointed me to missing package imports. Once I added the missing imports the original error went away.




回答3:


try adding this, it works for me

<dependency>
   <groupId>stax</groupId>
   <artifactId>stax-api</artifactId>
   <version>1.0.1</version>
</dependency>

<dependency>
   <groupId>stax</groupId>
   <artifactId>stax</artifactId>
   <version>1.2.0</version>
</dependency>

the maven bundle plugin can't automatically find the dependency stax:stax:1.2.0, besides you may need to manually export package com.bea.*

Below is an exmaple of osgi-fied apache poi using bnd https://github.com/stempler/bnd-platform-minimal

modify build.gradle to the code below:

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'org.standardout:bnd-platform:1.2.0'
        // uncomment line below if using Gradle 1.x
        // classpath 'org.codehaus.groovy:groovy-backports-compat23:2.3+'
    }
}

apply plugin: 'org.standardout.bnd-platform'

/* XXX Problem with new plugin notation: dependency of bnd-platform is not resolved correctly / cannot be loaded as plugin
plugins {
  id "org.standardout.bnd-platform" version "1.2.0"
}
*/

repositories {
    mavenCentral()
}

defaultTasks 'clean', 'updateSiteZip'

platform {
    fetchSources = true
    determineImportVersions = true

    override {
        optionalImport(
            // no version requirement for certain JRE provided packages
            // use wildcards to not enforce imports
            'javax.xml.*',
            // also make JUnit optional everywhere - so we can exclude it from products
            'junit.framework.*',
            'org.junit.*'
        )
    }

    def poiVersion = '3.15'
    feature id: 'org.apache.poi.osgi',
            name: 'Apache POI OSGI All In One',
            version: poiVersion, {
        // merged POI bundle
        merge(failOnDuplicate: false) {
            bundle "org.apache.poi:poi:$poiVersion"
            bundle "org.apache.poi:poi-ooxml:$poiVersion"
            bundle "org.apache.poi:poi-ooxml-schemas:$poiVersion"
            bundle "org.apache.xmlbeans:xmlbeans:2.6.0"
            bundle "com.github.virtuald:curvesapi:1.04"
            bundle "commons-codec:commons-codec:1.10"
            bundle "org.apache.commons:commons-collections4:4.1"
            bundle "stax:stax-api:1.0.1"
            bundle "stax:stax:1.2.0"

            bnd {
                symbolicName = 'org.apache.poi'
                bundleName = 'Apache POI'
                version = poiVersion
                // only provide poi packages as exported packages
                instruction 'Export-Package', "org.apache.poi.*;version=$version, com.bea.*"
                instruction 'Private-Package', '*'
                // don't import any poi packages
                prependImport '!org.apache.poi.*', '!org.apache.xmlbeans.*', '!com.graphbuilder.*', '!org.apache.commons.codec.*'
            }
        }
    }
}

task wrapper(type: Wrapper) {
    gradleVersion = '2.2'
}

run ./gradlew clean bundles updateSite to generate your bundle and repo for osgi-fied apache.poi



来源:https://stackoverflow.com/questions/34072711/pax-exam-issue-with-apache-poi-wrapped-bundle

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!