How to use Apache POI in OSGi

I want to use an Apache POI in OSGi to write an Excel workbook with OOXML Streaming API (SXSSF). The streaming API is available since POI 3.9.

Since the latest Apache POI 3.11 applications are not packages: What's the best way to get POI working in OSGi?

I tried two approaches:

  • embed cans directly into a single package that will use them
  • use POI jars prepackaged as packages

I am desperate to collect all the dependencies.

First about embedding a POI banner in my package: my bndtools file contains

-buildpath:  \
...
libs/dom4j-1.6.1.jar;version=file,\
libs/poi-3.11.jar;version=file,\
libs/poi-ooxml-3.11.jar;version=file,\
libs/poi-ooxml-schemas-3.11.jar;version=file

Private-Package:  \
...
org.openxmlformats.schemas.*,\
org.apache.poi.*,\
org.dom4j.*,\
com.microsoft.schemas.office.x2006.*,\
schemaorg_apache_xmlbeans.*,\
schemasMicrosoftComOfficeExcel.*,\
schemasMicrosoftComOfficeOffice.*,\
schemasMicrosoftComVml.*

      

The result is a package that imports many, many things, such as org.bouncycastle.asn1.x509

and org.junit

. I don't plan on encrypting or testing in my application - so those two are probably "optional" somehow. How can I indicate this? Is there a good way to collect all these dependencies?

Note: at least org.apache.commons.codec

and are required, com.sun.msv.datatype.xsd.lib

but they are already packages.


Using prepackaged jars I tried using org.apache.servicemix.bundles.poi

3.9_2. This is also required dom4j

, so I used prewrapped org.apache.servicemix.bundles.dom4j

, but it requires at least version 1.0 of javax.xml.stream

which my JVM / Felix OSGi advertises as a "only" version 0.0.0.1_007_JavaSE

. I fixed it manually (ugly) but then got stuck on a different dependency.

What's a good way?

+3


source to share


2 answers


We use Gradle with bnd-platform to create OSGi packages for our apps based on Maven dependencies. Not sure if this is a "good way", but this is how we create the target framework for our OSGi applications, of which Apache POI is a part. This is especially useful in cases where you need to adapt to packages (for example, make JUnit optional) or combine JARs (for example, due to class loading issues in OSGi) to get them to work.

I have installed a sample build with Apache POI package (and implicitly, its POM dependent dependencies) on GitHub. You can clone it ( sample-poi branch) and try running . The created packages will be in . ./gradlew clean bundles

build/plugins



Please note that any additional Maven dependencies will not be included by default and must be manually added to the build if you need to (due to limitations in Gradle ).

+3


source


I don't have a working example of this working, but this piece of documentation might be helpful to you.

Can POI be used with OSGI?



Starting with POI 3.16, there is a workaround for OSGI context. handling the classloader, i.e. it replaces the current threading context classloader with a constrained class view implementation. This will result in IllegalStateExceptions as xmlbeans cannot find the definition xml schema in this shorthand. The workaround is to initialize the classloader delegate to POIXMLTypeLoader, which is the default classloader of the current context. The initialization must take place before any other OOXML-related calls. The class in the example can be any class that is part of the poi-ooxml schema or OOXML schema: POIXMLTypeLoader.setClassLoader (CTTable.class.getClassLoader ());

+1


source







All Articles