如何在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");
验证步骤
- 执行
mvn clean package打包插件,确认Shade插件正常执行,生成包含重定位类的jar包 - 将插件jar包部署到Jira的
plugins/installed-plugins目录,重启Jira - 测试Excel导出功能,确认
ClassCastException和流异常消失
内容的提问来源于stack exchange,提问作者Matti Kiviharju
相关产品推荐
相关产品推荐

