javadependenciesosgiapache-poibndtools

How to use Apache POI in OSGi


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

As the latest Apache POI 3.11 jars are not bundles: What's the best way to get POI working in OSGi?

I tried two approaches:

  1. embed the jars directly in the only bundle which will be using them
  2. use POI jars prewrapped as bundles

I am despairing in getting all dependencies together.

First about embedding the POI jar in my bundle: 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.*

This results in a bundle which imports many, many things like for example org.bouncycastle.asn1.x509 and org.junit. I don't plan to encrypt or test in my application - so these two are probably somehow "optional". How can I specify this? Is there a good way of collecting all these dependencies?

Note: at least org.apache.commons.codec and com.sun.msv.datatype.xsd.lib are additionally required, but they are already bundles.


Using prewrapped jars, I tried using org.apache.servicemix.bundles.poi 3.9_2. This also requires dom4j so I used the prewrapped org.apache.servicemix.bundles.dom4j but that requires at least version 1.0 of javax.xml.stream which my JVM/Felix OSGi advertises as "only" version 0.0.0.1_007_JavaSE. I fixed this by hand (ugly), but then got stuck on another dependency.

What's the good way?


Solution

  • We use Gradle with bnd-platform to build OSGi bundles for our applications based on Maven dependencies. No sure if this is "the good way", but this is how we build the target platform for our OSGi based applications, Apache POI being part of that. It's especially useful in cases where you have to do adaptions to bundles (e.g. make JUnit optional) or merge JARs (e.g. due to classloading issues in OSGi) to make them work.

    I set up an example build with an Apache POI bundle (and implicitly, its POM-defined dependencies) on GitHub. You can clone it (sample-poi branch) and try it running ./gradlew clean bundles. Created bundles will be in build/plugins.

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