簡體   English   中英

OSGi中的Apache POI 3.17

[英]Apache POI 3.17 in OSGi

序言:我已經看過這個問題 ,但是顯然是關於POI的較早版本,從那時起Apache就違反了所有Java標准。

問題:我的目標是使POI與OSGi一起使用。 到目前為止,我很確定這是不可能的,但是也許你們中的一個有一個好主意。 到目前為止我嘗試過的是:

1)捆綁JAR

最簡單的方法是將捆綁包信息直接添加到POI罐中(另一個答案包含有關如何執行操作的詳細信息)。 這是行不通的,因為JAR會導出相同的包,例如poi-3.17.jarpoi-ooxml-3.17.jar都導出org.apache.poi ,這在OSGi中是不允許的(並且在標准Java中,這是最佳做法也有單獨的軟件包)。

2)使用預包裝的插件

我找到了org.apache.servicemix.bundles.poi ,它是由對OSGi的工作原理不了解的人創建的(也許是Apache的人?)。 它包含任何JAR文件中都不存在的依賴,尤其是導入包org.junit令我擔心。

我無法使它正常工作,因為還不是所有必需的進口貨物都是捆綁銷售的。 由於捆綁包顯然很破損,所以我很快放棄了。

3)使用帶有lib文件夾的插件

很難找到正確的導入和導出包。 最終,這將失敗,因為POI JAR導出了標准軟件包(例如xmlbeans javax.xml )。

4)將源復制到插件

這可能是我的最愛。 將源代碼復制到它們自己的插件中時,會出現編譯錯誤 JAR poi-ooxml-3.17.jar需要一個名為org.etsi.uri.x01903.v13.SignaturePolicyIdType的類。 該類包含在poi-ooxml-schemas-3.17.jar中 ,但令人不安的是它的名稱是SignaturePolicyIdentifierType

5)詢問Apache

有一個問題“ OSI可以使用POI嗎?” 在常見問題解答中

從POI 3.16開始,有一個針對OSGI上下文類加載器處理的解決方法,即,它使用受限類視圖的實現替換了當前上下文類加載器的線程。 這將導致IllegalStateExceptions,因為xmlbeans在此簡化視圖中找不到xml模式定義。 解決方法是初始化POIXMLTypeLoader的類加載器委托,該委托默認為當前線程上下文類加載器。 初始化應在任何其他與OOXML相關的調用之前進行。 示例中的類可以是poi-ooxml-schema或ooxml-schema的一部分的任何類: POIXMLTypeLoader.setClassLoader(CTTable.class.getClassLoader());

我沒有嘗試過,因為這對我來說沒有任何意義:他們如何將非標准的JAR捆綁在一起? 以及在加載類后如何設置類加載器甚至會有所幫助?

問題:有什么方法可以使當前的POI與OSGi一起使用?

注意:我只是發現了這個問題 ,但這是針對更舊版本的POI。 但這顯然是一個持續的問題。

我通過構建自己的3.17 OSGi捆綁軟件使其工作,我將其放入了Virgo / repository / usr:

<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文件:

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
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM