Payara项目使用Apache POI XSSFWorkbook时遭遇NoSuchFieldError: Factory错误
问题描述
在基于Java EE技术栈的Payara项目中,调用DataUploadBean类的createTemplateForItemWithFeeUpload方法创建XSSFWorkbook实例时,触发如下运行时错误:
java.lang.NoSuchFieldError: Factory at org.apache.poi.xssf.usermodel.XSSFWorkbook.onWorkbookCreate(XSSFWorkbook.java:506) at org.apache.poi.xssf.usermodel.XSSFWorkbook.<init>(XSSFWorkbook.java:233) // ... (更多堆栈信息)
上下文说明
项目pom.xml中引入了Apache POI 5.2.5版本的相关依赖:
<!-- Apache POI --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>5.2.5</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>5.2.5</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-excelant</artifactId> <version>5.2.5</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-scratchpad</artifactId> <version>5.2.5</version> </dependency> <dependency> <groupId>fr.opensagres.xdocreport</groupId> <artifactId>org.apache.poi.xwpf.converter.xhtml</artifactId> <version>1.0.6</version> </dependency>
报错相关方法
public void createTemplateForItemWithFeeUpload() { try { // 以下代码触发NoSuchFieldError XSSFWorkbook workbook = new XSSFWorkbook(); // 其他代码... } catch (Exception e) { // 异常处理... } }
错误成因与排查解决思路
错误成因
NoSuchFieldError本质是类版本不一致导致的运行时类加载冲突:编译时项目依赖的Apache POI 5.2.5中,XSSFWorkbook相关类存在Factory字段,但运行时JVM加载了旧版本的POI类(该类无Factory字段),从而触发错误。
从依赖配置看,核心冲突来源是fr.opensagres.xdocreport:org.apache.poi.xwpf.converter.xhtml:1.0.6——这个依赖默认依赖旧版本的Apache POI(通常是3.x/4.x系列),会间接引入与项目指定的5.2.5版本不兼容的POI类。
排查思路
- 检查依赖树:执行
mvn dependency:tree命令,查看所有org.apache.poi开头的依赖,确认是否存在非5.2.5版本的间接依赖。 - 排查服务器自带库:检查Payara服务器的
domain/lib或lib目录,确认是否存在旧版本POI的jar包——服务器自带库优先级高于项目依赖,会导致类加载冲突。 - 验证类加载路径:通过Payara的管理控制台或日志,查看运行时加载的
XSSFWorkbook类来自哪个jar包,确认是否为项目指定的5.2.5版本。
解决建议
- 排除冲突依赖:修改pom.xml,在xdocreport转换器依赖中排除所有Apache POI相关子依赖,强制使用项目指定的5.2.5版本:
<dependency> <groupId>fr.opensagres.xdocreport</groupId> <artifactId>org.apache.poi.xwpf.converter.xhtml</artifactId> <version>1.0.6</version> <exclusions> <exclusion> <groupId>org.apache.poi</groupId> <artifactId>*</artifactId> </exclusion> </exclusions> </dependency>
- 清理服务器冲突库:如果Payara服务器自带旧POI jar,直接移除这些文件,避免干扰项目依赖。
- 强制更新依赖:执行
mvn clean install -U命令,清理本地Maven缓存并重新构建项目,确保所有依赖都是指定版本。 - 验证部署包:检查项目部署到Payara后的
WEB-INF/lib目录,确认所有POI相关jar都是5.2.5版本,无旧版本混入。
内容的提问来源于stack exchange,提问作者Buddhika Ariyaratne
相关产品推荐
相关产品推荐

