You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Jira 9.11.2中使Apache POI 5.2.0正常运行?

解决Jira 9.11.2集成Apache POI 5.2.0的类加载冲突问题

问题核心分析

出现ClassCastException的根本原因是OSGi类加载器隔离冲突:

  • Jira基于Felix框架运行,javax.xml.parsers.DocumentBuilderFactory由Felix的Bundle类加载器加载
  • 插件依赖的org.apache.xerces.jaxp.DocumentBuilderFactoryImpl由Web应用类加载器(ParallelWebappClassLoader)加载
  • 两个类加载器加载的类属于不同运行时模块,无法进行类型转换

同时代码存在输出流使用错误:重复获取resp.getOutputStream()并同时使用PrintWriter和OutputStream写入,会导致流状态异常。


完整POM配置方案

1. 依赖调整

移除手动添加的xercesImpl依赖(POI会自动引入,后续通过Shade插件重定位),添加Jira API依赖并设置正确范围,调整POI相关依赖配置:

<properties>
    <jira.version>9.11.2</jira.version>
    <maven.compiler.source>11</maven.compiler.source>
    <maven.compiler.target>11</maven.compiler.target>
</properties>

<dependencies>
    <!-- Jira API 依赖,使用provided范围避免打包进插件 -->
    <dependency>
        <groupId>com.atlassian.jira</groupId>
        <artifactId>jira-api</artifactId>
        <version>${jira.version}</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>com.atlassian.jira</groupId>
        <artifactId>jira-core</artifactId>
        <version>${jira.version}</version>
        <scope>provided</scope>
    </dependency>

    <!-- Apache POI 相关依赖,compile范围用于Shade重定位 -->
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi</artifactId>
        <version>5.2.0</version>
        <scope>compile</scope>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>5.2.0</version>
        <scope>compile</scope>
    </dependency>
    <!-- 移除poi-ooxml-lite,避免和poi-ooxml冲突 -->
    <!-- <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml-lite</artifactId>
        <version>5.2.0</version>
    </dependency> -->
    <dependency>
        <groupId>org.apache.xmlbeans</groupId>
        <artifactId>xmlbeans</artifactId>
        <version>5.0.3</version>
        <scope>compile</scope>
    </dependency>

    <!-- 其他必要依赖 -->
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-api</artifactId>
        <version>2.17.1</version>
        <scope>compile</scope>
    </dependency>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-core</artifactId>
        <version>2.17.1</version>
        <scope>compile</scope>
    </dependency>
    <dependency>
        <groupId>com.zaxxer</groupId>
        <artifactId>SparseBitSet</artifactId>
        <version>1.2</version>
        <scope>compile</scope>
    </dependency>
</dependencies>

2. Maven Shade插件完整配置

通过Shade插件将POI、XMLBeans、Xerces等冲突包重定位到插件私有包路径,避免和Jira自带类冲突:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <version>3.4.1</version> <!-- 使用较新版本兼容Java 11 -->
            <configuration>
                <createDependencyReducedPom>false</createDependencyReducedPom>
                <relocations>
                    <!-- 重定位POI核心包 -->
                    <relocation>
                        <pattern>org.apache.poi</pattern>
                        <shadedPattern>fi.i4ware.plugin.timesheet.tfj.org.apache.poi</shadedPattern>
                    </relocation>
                    <!-- 重定位XMLBeans -->
                    <relocation>
                        <pattern>org.apache.xmlbeans</pattern>
                        <shadedPattern>fi.i4ware.plugin.timesheet.tfj.org.apache.xmlbeans</shadedPattern>
                    </relocation>
                    <!-- 重定位Xerces相关包 -->
                    <relocation>
                        <pattern>org.apache.xerces</pattern>
                        <shadedPattern>fi.i4ware.plugin.timesheet.tfj.org.apache.xerces</shadedPattern>
                    </relocation>
                    <!-- 重定位POI依赖的其他XML工具类 -->
                    <relocation>
                        <pattern>org.apache.openxml4j</pattern>
                        <shadedPattern>fi.i4ware.plugin.timesheet.tfj.org.apache.openxml4j</shadedPattern>
                    </relocation>
                </relocations>
                <!-- 排除签名文件,避免打包冲突 -->
                <filters>
                    <filter>
                        <artifact>*:*</artifact>
                        <excludes>
                            <exclude>META-INF/*.SF</exclude>
                            <exclude>META-INF/*.DSA</exclude>
                            <exclude>META-INF/*.RSA</exclude>
                        </excludes>
                    </filter>
                </filters>
            </configuration>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>shade</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

代码修复建议

1. 输出流处理修复

删除重复的输出流获取代码,仅使用OutputStream写入Excel,同时设置正确的响应头:

// 设置Excel响应头
resp.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
resp.setHeader("Content-Disposition", "attachment; filename=\"worklog-export.xlsx\"");

// 仅使用一个输出流
OutputStream out = resp.getOutputStream();
wb.write(out);
out.flush();
out.close();

2. 强制指定XML解析器实现

在初始化POI之前,强制设置使用JRE自带的DocumentBuilderFactory,避免SPI加载冲突:

// 在创建Workbook之前添加以下代码
System.setProperty("javax.xml.parsers.DocumentBuilderFactory", 
    "com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl");

验证步骤

  1. 执行mvn clean package打包插件,确认Shade插件正常执行,生成包含重定位类的jar包
  2. 将插件jar包部署到Jira的plugins/installed-plugins目录,重启Jira
  3. 测试Excel导出功能,确认ClassCastException和流异常消失

内容的提问来源于stack exchange,提问作者Matti Kiviharju

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 09:35:01