【问题标题】:How to use Apache POI in OSGi如何在 OSGi 中使用 Apache POI
【发布时间】:2015-07-01 18:52:02
【问题描述】:

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

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

我尝试了两种方法:

  1. 将 jar 直接嵌入到将使用它们的唯一包中
  2. 使用预先打包成包的 POI jar

我对将所有依赖项放在一起感到绝望。

首先关于在我的包中嵌入 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,但它们已经是捆绑包。


使用预包装的罐子,我尝试使用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。我手动修复了这个(丑陋的),但后来卡在了另一个依赖项上。

有什么好办法?

【问题讨论】:

  • 你在正确的轨道上,坚持下去 :-) servicemix 包已经准备好 OSGi,如果这需要更多的依赖项,也安装它们。对于 javax.xml.stream,您还可以查找相应的包。您还缺少哪些其他依赖项?
  • 在运行时,它找不到 poi-ooxml-schemas 中的类。有捆绑包吗?同时我尝试嵌入它,但 v.3.9 没有所有必需的类(缺少一些 ...math 包)

标签: java dependencies osgi apache-poi bndtools


【解决方案1】:

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

我在 GitHub 上设置了一个 example build with an Apache POI bundle(隐含地,它的 POM 定义的依赖项)。您可以克隆它(sample-poi 分支)并尝试运行./gradlew clean bundles。创建的捆绑包将位于build/plugins

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

【讨论】:

  • Stempler,感谢您的快速解决方案!您是使用 Gradle 构建整个依赖包,还是仅用于生成依赖包?
  • @Andrew 就我个人而言,我只使用该构建来创建具有第三方依赖项的 P2 存储库,然后在 Maven Tycho 构建中使用该存储库。 Here 是一个在包含构建的上下文中使用 bnd-platform 的示例。也许还有一种方法可以将它与Wuff Gradle plugins 结合起来,但到目前为止,AFAIK 还没有人尝试过。
【解决方案2】:

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

Can POI be used with OSGI?

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

【讨论】:

    猜你喜欢
    • 2018-12-16
    • 2014-06-09
    • 2022-12-13
    • 1970-01-01
    • 1970-01-01
    • 2011-12-25
    • 2016-10-13
    • 2012-11-02
    • 1970-01-01
    相关资源
    最近更新 更多