如何在OSGi中使用Apache POI

我想在OSGi中使用Apache POI来编写带有流式OOXML API(SXSSF)的Excel工作簿。 流式API自POI 3.9起可用。

由于最新的Apache POI 3.11jar不是捆绑包: 在OSGi中使POI工作的最佳方法是什么?

我尝试了两种方法:

  1. 将jar子直接嵌入将使用它们的唯一束中
  2. 使用POIjar作为捆绑包装预先包装

我绝望地将所有依赖项放在一起。

首先关于在我的包中嵌入POI jar:我的bndtools文件包含

-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.* 

这会产生一个包,它导入很多很多东西,例如org.bouncycastle.asn1.x509org.junit 。 我不打算在我的应用程序中加密或测试 – 所以这两个可能在某种程度上是“可选的”。 我怎么指定这个? 有没有一种收集所有这些依赖关系的好方法?

注意:至少还需要org.apache.commons.codeccom.sun.msv.datatype.xsd.lib ,但它们已经是捆绑包。


使用预先包装的jar子,我尝试使用org.apache.servicemix.bundles.poi 3.9_2。 这也需要dom4j所以我使用了预先包装好的org.apache.servicemix.bundles.dom4j但是至少需要javax.xml.stream 1.0版本,我的JVM / Felix OSGi将其作为“仅”版本0.0.0.1_007_JavaSE 。 我手动修复了这个问题(丑陋),但后来陷入了另一个依赖关系。

什么是好方法?

我们使用Gradle和bnd-platform为我们基于Maven依赖的应用程序构建OSGi包。 不确定这是否是“好方法”,但这就是我们为基于OSGi的应用程序构建目标平台的方式,Apache POI就是其中的一部分。 它在你必须对bundle进行适应(例如使JUnit可选)或合并JAR(例如由于OSGi中的类加载问题)以使它们工作的情况下特别有用。

我在GitHub上使用Apache POI包 (并隐式地,它的POM定义的依赖项)设置了一个示例构建 。 您可以克隆它( sample-poi branch)并尝试运行./gradlew clean bundles 。 创建的包将在build/plugins

请注意,默认情况下不会包含任何可选的Maven依赖项,如果需要,必须手动添加到构建中(由于Gradle中的限制 )。

我没有这方面的工作示例,但这些文档可能对您有所帮助。

POI可以与OSGI一起使用吗?

从POI 3.16开始,OSGIs上下文类加载器处理有一个解决方法,即它将线程当前上下文类加载器替换为有限类视图的实现。 这将导致IllegalStateExceptions,因为xmlbeans在此缩减视图中找不到xml架构定义。 解决方法是初始化POIXMLTypeLoader的类加载器委托,默认为当前线程上下文类加载器。 初始化应该在任何其他OOXML相关调用之前进行。 示例中的类可以是任何类,它是poi-ooxml-schema或ooxml-schema的一部分:POIXMLTypeLoader.setClassLoader(CTTable.class.getClassLoader());