我想在OSGi中使用ApachePOI来编写带有流式OOXMLneneneba API(SXSSF)的Excel工作簿。流式API从POI 3.9开始提供。
由于最新的Apache POI 3.11 jar不是捆绑包:让POI在OSGi中工作的最佳方式是什么
我尝试了两种方法:
- 将jar直接嵌入到将使用它们的唯一捆绑包中
- 使用预先包装成捆的POI罐子
我对把所有依赖放在一起感到绝望。
首先关于在我的捆绑包中嵌入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.x509
和org.junit
。我不打算在我的应用程序中进行加密或测试,所以这两个可能在某种程度上是"可选的"。如何指定?有没有一种收集所有这些依赖关系的好方法?
注意:至少需要org.apache.commons.codec
和com.sun.msv.datatype.xsd.lib
,但它们已经是捆绑包。
使用预包装的罐子,我尝试使用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平台为基于Maven依赖关系的应用程序构建OSGi捆绑包。不确定这是否是"好方法",但这就是我们为基于OSGi的应用程序构建目标平台的方式,ApachePOI就是其中的一部分。在必须对捆绑包进行自适应(例如,使JUnit成为可选的)或合并JAR(例如,由于OSGi中的类加载问题)以使其工作的情况下,它尤其有用。
我在GitHub上用ApachePOI捆绑包(隐含地,它的POM定义的依赖项)建立了一个示例构建。您可以克隆它(示例poi分支)并尝试运行./gradlew clean bundles
。创建的捆绑包将在build/plugins
中。
请注意,默认情况下,任何可选的Maven依赖项都不会包括在内,如果需要,必须手动添加到构建中(由于Gradle中的限制)。
我没有这方面的工作示例,但这部分文档可能对您有所帮助。
POI可以与OSGI一起使用吗?
从POI 3.16开始,OSGI上下文有一个变通方法类加载器处理,即它替换线程当前上下文实现有限类视图的类加载器。这将导致IllegalStateException,因为xmlbeans找不到xml模式这个简化视图中的定义。解决方法是初始化POIXMLTypeLoader的classloader委托,默认为当前线程上下文类加载器。初始化应该需要放置在任何其他OOXML相关调用之前。示例中的类可以是任何类,它是poi-ooxml模式的一部分,或者ooxml架构:POIXMLTypeLoader.setClassLoader(CTTable.class.getClassLoader);