0

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.

Frank Reno
  • 243
  • 3
  • 9
  • Not sure why POI is mentioned here. it doesn't seem to be involved in the exception at all. – Jim Garrison Dec 03 '15 at 17:59
  • Thanks Jim, I included it because there have been several related posts about the issue, specifically with POI. I'll drop the tag since the stack does explicitly point to pax exam. – Frank Reno Dec 03 '15 at 18:07
  • Which bundle is supposed to provide `com.bea.xml.stream.EventFactory` ? Why is it referenced at all? This is not what you'd normally expect to be loaded by `javax.xml.stream.XMLEventFactory.newInstance()`. Which test container are you using? And which version of Pax Exam? Try to narrow down your problem to the XML stuff. It does not seem to be related to POI or Pax Exam at all. – Harald Wellmann Dec 03 '15 at 21:15
  • Thank you Harald. From what I could gather online, the POI library has a dependency on stax and that is responsible for providing com.bea.xml.stream.EventFactory. I added this in to my dependencies and I still get the same error. I am using the Karaf test container, version 4.6.0. – Frank Reno Dec 03 '15 at 22:31

3 Answers3

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>

  • Your welcome. In that case please accept my answer :) – Csákány Róbert Jan 05 '16 at 18:05
  • Hi Csakany, I'm trying to use POI in atlassian jira plugin. I have modified my pom.xml as you explained but now I'm taking this error; Unable to resolve 165.0: missing requirement [165.0] osgi.wiring.package; (osgi.wiring.package=org.apache.xml.resolver) Do you have any idea? – Ömer Faruk AK Aug 18 '16 at 07:16
  • Sorry for late answer. Its a different story. I can collect what bundle is used by POI, and I can give a list. The reason is xml-resolver is presented by some karaf bunlde, so have to collect all transitive bundle dependencies. The bunlde is missed: mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.xmlresolver/1.2_5. – Csákány Róbert Sep 06 '16 at 17:54
0

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.

Frank Reno
  • 243
  • 3
  • 9
-1

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

user29131
  • 1
  • 1