简体   繁体   English

Apache POI、Excel 2007+ XML 和 OSGI

[英]Apache POI, Excel 2007+ XML, and OSGI

For a project I'm trying to get Excel XML functionality using Apache POI to work with OSGI.对于一个项目,我正在尝试使用 Apache POI 获得 Excel XML 功能以与 OSGI 一起使用。

I've tried the POI ServiceMix bundle, but this was missing the ooxml-schemas jar.我已经尝试过 POI ServiceMix 包,但是缺少 ooxml-schemas jar。 Adding the jar to the bundle and including it in the manifest didn't seem to work.将 jar 添加到捆绑包并将其包含在清单中似乎不起作用。

Then I tried to creating wrapper bundles for POI 3.10, but also to no avail.然后我尝试为 POI 3.10 创建包装包,但也无济于事。 Same error.同样的错误。

Caused by: java.lang.ClassNotFoundException: org.apache.xmlbeans.impl.schema.SchemaTypeSystemImpl not found by org.apache.poi [8]
at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1532)
at org.apache.felix.framework.BundleWiringImpl.access$400(BundleWiringImpl.java:75)
at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:1955)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Unknown Source)
... 105 more

Subsequent calls lead to the following:后续调用会导致以下结果:

Caused by: java.lang.NoClassDefFoundError: Could not initialize class org.openxmlformats.schemas.drawingml.x2006.main.ThemeDocument
at org.openxmlformats.schemas.drawingml.x2006.main.ThemeDocument$Factory.parse(Unknown Source)
at org.apache.poi.xssf.model.ThemesTable.<init>(ThemesTable.java:44)
... 93 more

XMLBeans is available as a bundle exporting all of its packages, and I've tried the ServiceMix bundle as well as making one out of the jar included with POI 3.10. XMLBeans 可以作为一个包导出它的所有包,我已经尝试了 ServiceMix 包以及从 POI 3.10 包含的 jar 中制作一个包。

Could someone guide me through the process of creating a working OSGI bundle that can handle Excel 2007+ XML documents?有人可以指导我完成创建可以处理 Excel 2007+ XML 文档的工作 OSGI 包的过程吗? Help much appreciated.非常感谢帮助。

The problem is that the classes from org.apache.poi.ooxml-schemas call Class.forName("org.apache.xmlbeans.impl.schema") , so you need an import of this package in the manifest of your ooxml-schemas bundle.问题是来自org.apache.poi.ooxml-schemas的类调用Class.forName("org.apache.xmlbeans.impl.schema") ,所以你需要在你的 ooxml-schemas 清单中导入这个包捆。

I solved it by adding <DynamicImport-Package>*</DynamicImport-Package> to the configuration of the maven-bundle-plugin when building the ooxml-schemas bundle.我通过在构建 ooxml-schemas 包时将<DynamicImport-Package>*</DynamicImport-Package>maven-bundle-plugin的配置来解决它。

We use a bundle that merges poi , poi-ooxml and poi-ooxml-schemas to work around the class loading issue.我们使用一个合并poipoi-ooxmlpoi-ooxml-schemas来解决类加载问题。

For that we use Gradle with bnd-platform .为此,我们将 Gradle 与bnd-platform 结合使用 It allows building and adapting OSGi bundles based on Maven dependencies.它允许基于 Maven 依赖项构建和调整 OSGi 包。 Merging JARs to a combined bundle can also be done easily.也可以轻松地将 JAR 合并到组合包中。

I set up an example build with an Apache POI bundle (and implicitly, its POM-defined dependencies) on GitHub.我在 GitHub 上设置了一个带有 Apache POI 包(以及其 POM 定义的依赖项)的示例构建 It's an excerpt from or own configuration for building the complete target platform for an OSGi based application.它是为基于 OSGi 的应用程序构建完整目标平台的摘录或自己的配置。

You can clone it ( sample-poi branch) and try it running ./gradlew clean bundles .您可以克隆它( sample-poi分支)并尝试运行./gradlew clean bundles Created bundles will be in build/plugins .创建的包将在build/plugins

Caused by: java.lang.ClassNotFoundException:
  org.apache.xmlbeans.impl.schema.SchemaTypeSystemImpl
  not found by org.apache.poi [8]

This means that code within bundle org.apache.poi looks for class SchemaTypeSystemImpl of package org.apache.xmlbeans.impl.schema and can't find it.这意味着,包内代码org.apache.poi外观类SchemaTypeSystemImpl包的org.apache.xmlbeans.impl.schema并不能找到它。 Given that both class and package look like implementation classes, I'd hypothesize that it's proper and correct that they aren't accessible outside their bundle.鉴于类和包看起来都像实现类,我假设它们不能在包外访问是正确和正确的。

Could you add the complete stack trace for the first exception, so that the call site of the Class.forName() will be visible?您能否为第一个异常添加完整的堆栈跟踪,以便Class.forName()的调用站点可见? In all likelihood that's just the downstream of a configuration issue, but it will help narrow it down.这很可能只是配置问题的下游,但这将有助于缩小问题的范围。

I was able to use the poi library in OSGi by adding the following bundles to the run bundles:通过将以下包添加到运行包中,我能够在 OSGi 中使用 poi 库:
* org.apache.servicemix.bundles.poi * org.apache.servicemix.bundles.poi
* org.apache.servicemix.bundles.xmlbeans * org.apache.servicemix.bundles.xmlbeans
* commons-collections4 * Commons-collections4
* commons-compress * 公共压缩
* commons-math3 * commons-math3
* Saxon DOM 8.9.0.4-osgi * 撒克逊 DOM 8.9.0.4-osgi

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM