首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >OSGi中的ApachePOI3.17

OSGi中的ApachePOI3.17
EN

Stack Overflow用户
提问于 2018-07-09 06:39:40
回答 1查看 1.6K关注 0票数 5

序言:--我见过这个问题,但很明显它是关于POI的旧版本的,从那时起,Apache违背了所有的这个问题标准。

问题:,我的目标是让POI与OSGi一起工作。到目前为止,我很确定这是不可能的,但也许你们中的一个有个好主意。到目前为止我尝试过的是:

1)捆绑JAR

最简单的方法是将捆绑信息直接添加到POI jars中(另一个答案有关于如何实现的详细信息)。这是行不通的,因为JAR导出相同的包,例如poi-3.17.jar和poi-ooxml-3.17.jar都导出org.apache.poi,这在OSGi中是不允许的(在标准Java中,拥有单独的包也是一种最佳实践)。

2)使用预先打包的插件

我找到了org.apache.servicemix.bundles.poi,它是由不了解OSGi工作原理的人创建的(可能是Apache?)。它包含在任何JAR中都不存在的摇摇欲坠的依赖项,尤其是导入包org.junit让我担心。

我无法让它发挥作用,因为并不是所有必要的进口都是捆绑的。既然那包裹显然坏了,我很快就放弃了。

3)使用带有lib文件夹的插件()

很难找到正确的进出口包装。这最终失败了,因为POI导出标准包(比如来自javax.xmlxmlbeans)。

4)将源代码复制到插件中。

这可能是我的最爱。当您将源代码复制到它们自己的插件中时,就会得到编译错误。JAR poiooxml3.17.jar需要一个名为org.etsi.uri.x01903.v13.SignaturePolicyIdType的类。类包含在poi-ooxml 3.17.jar中,但令人不安的事实是它的名称是SignaturePolicyIdentifierType

5)问Apache

有一个问题是“POI可以与OSGI一起使用吗?”在常见问题中

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

我没有试过,因为这对我来说没有任何意义:他们怎么会把他们的不标准的容器打包成包呢?在类加载之后,如何设置类加载器,甚至是帮助?

问题:有没有办法让当前的POI与OSGi一起工作?

注意:我刚刚找到了这个问题,但是它是针对更老版本的POI的。但很明显这是个持续的问题。

EN

回答 1

Stack Overflow用户

发布于 2018-08-01 22:38:38

我构建了自己的3.17 OSGi包,并将其放在处女座/存储库/usr中:

代码语言:javascript
复制
<project ..>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.1.7</version>

<packaging>bundle</packaging>

<name>OSGi-wrapped poi-ooxml</name>

<dependencies>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>3.17</version>
    </dependency>
    <dependency>
        <groupId>com.github.virtuald</groupId>
        <artifactId>curvesapi</artifactId>
        <version>1.04</version>
    </dependency>
    <dependency>
        <groupId>org.apache.xmlbeans</groupId>
        <artifactId>xmlbeans</artifactId>
        <version>2.3.0</version>
    </dependency>
    <dependency>
        <groupId>stax</groupId>
        <artifactId>stax-api</artifactId>
        <version>1.0.1</version>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml-schemas</artifactId>
        <version>3.17</version>
    </dependency>
    <dependency>
        <groupId>commons-codec</groupId>
        <artifactId>commons-codec</artifactId>
        <version>1.10</version>
    </dependency>
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-collections4</artifactId>
        <version>4.1</version>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi</artifactId>
        <version>3.17</version>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.felix</groupId>
            <artifactId>maven-bundle-plugin</artifactId>
            <version>2.3.7</version>
            <extensions>true</extensions>
            <configuration>
                <instructions>
                    <Export-Package>org.apache.poi.*</Export-Package>
                    <!--
                    One important thing to note: if you are not exporting a package, you add it to the Private-Package instruction.
                    Otherwise, the classes inside the package will not be copied to your bundle, as the default value of this instruction is empty.
                    -->
                    <Private-Package>org.openxmlformats.*,org.apache.commons.*,com.graphbuilder.curve.*,org.apache.xmlbeans.*,schemaorg_apache_xmlbeans.*,schemasMicrosoftComOfficeExcel.*</Private-Package>
                </instructions>
            </configuration>
        </plugin>
    </plugins>
</build>

然后在我的调用代码中,我创建一个线程并使用父类加载器。想听一个更好的方法-这不是琐碎的设置。如果Apache有OSGi包,那就太好了。我可能有额外的或缺少的步骤,但是正在用以下代码生成Excel文件:

代码语言:javascript
复制
public void write(OutputStream out) throws IOException {

    Runnable sheetCreator = new Runnable() {
        @Override
        public void run() {
            Workbook workbook = null;
            try {
                // 3.16, but now obsolete
                // POIXMLTypeLoader.setClassLoader(CTTable.class.getClassLoader());
                workbook = new XSSFWorkbook();
                buildWorkbook(workbook);
                workbook.write(out);
                out.flush();
            } catch (Throwable t) {
                // log
            } finally {
                if (workbook != null) {
                    try {
                        workbook.close();
                    } catch (IOException e) {
                        // log
                    }
                }
            }
        }
    };

    try {
        Thread thread = Thread.currentThread();
        ClassLoader cl = thread.getContextClassLoader();

        Thread th = new Thread(sheetCreator);

        th.setContextClassLoader(cl.getParent());
        th.start();
        th.join();
    } catch (Throwable t) {
        // log
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51239464

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档