升级Apache POI 5.2.3后遇NoSuchFieldError: Factory错误,求排查版本冲突
问题描述
近期将Apache POI升级至5.2.3版本(使用JDK 1.8),创建Workbook时抛出如下异常:
Exception in thread "main" java.lang.NoSuchFieldError: Factory
at org.apache.poi.xssf.model.ThemesTable.readFrom(ThemesTable.java:119)
at org.apache.poi.xssf.model.ThemesTable.(ThemesTable.java:87)
at org.apache.poi.ooxml.POIXMLFactory.createDocumentPart(POIXMLFactory.java:61)
at org.apache.poi.ooxml.POIXMLDocumentPart.read(POIXMLDocumentPart.java:661)
at org.apache.poi.ooxml.POIXMLDocument.load(POIXMLDocument.java:165)
at org.apache.poi.xssf.usermodel.XSSFWorkbook.(XSSFWorkbook.java:260)
at org.apache.poi.xssf.usermodel.XSSFWorkbookFactory.createWorkbook(XSSFWorkbookFactory.java:118)
at org.apache.poi.xssf.usermodel.XSSFWorkbookFactory.create(XSSFWorkbookFactory.java:98)
at org.apache.poi.xssf.usermodel.XSSFWorkbookFactory.create(XSSFWorkbookFactory.java:36)
at org.apache.poi.ss.usermodel.WorkbookFactory.lambda$create$2(WorkbookFactory.java:224)
at org.apache.poi.ss.usermodel.WorkbookFactory.wp(WorkbookFactory.java:329)
at org.apache.poi.ss.usermodel.WorkbookFactory.create(WorkbookFactory.java:224)
at org.apache.poi.ss.usermodel.WorkbookFactory.create(WorkbookFactory.java:185)
测试代码:
File file = new File("L://WRK/Java/designchecker/common/configfiles/Styleset.xlsx"); try { Workbook workbook = WorkbookFactory.create(new FileInputStream(file)); } catch (Exception ex) { ex.printStackTrace(); }
已确认存在版本不匹配问题,但无法定位具体冲突库,需排查解决。
问题根源
这个异常的核心是类路径中存在版本不兼容的POI相关依赖:org.openxmlformats.schemas.drawingml.x2006.main.ThemeDocument类的Factory字段找不到,通常是以下原因导致:
poi-ooxml-schemas或ooxml-schemas版本与POI 5.2.3不匹配- 引入了旧版本的XML处理依赖(如xmlbeans)
- 项目中混入了不同版本的POI子模块
排查与解决步骤
强制统一POI所有子模块版本
POI 5.2.3要求poi、poi-ooxml、poi-ooxml-schemas等所有子模块版本完全一致。检查依赖配置,确保这些组件版本均为5.2.3,同时排除任何旧版本的POI依赖(通过构建工具的排除规则)。检查xmlbeans版本兼容性
POI 5.2.3依赖xmlbeans 3.1.0,若项目中引入了2.x等旧版本xmlbeans,会导致类加载冲突。建议直接使用POI依赖传递的xmlbeans版本,避免手动指定其他版本。排查附属依赖版本
POI 5.2.3依赖curvesapi 1.0.6,若存在旧版本的curvesapi也可能引发间接冲突,需确保该依赖版本与POI匹配。分析依赖树定位冲突
使用构建工具的依赖分析命令,找出实际生效的依赖版本:- Maven:执行
mvn dependency:tree,搜索所有POI、xmlbeans相关条目,标记版本不一致的依赖 - Gradle:执行
gradle dependencies,同样排查版本冲突节点
- Maven:执行
替换旧版ooxml依赖
POI 5.x推荐使用poi-ooxml-schemas(POI裁剪后的轻量版本),而非旧的ooxml-schemas,避免完整schema包与POI的冲突。
示例Maven依赖配置
<dependencies> <!-- Apache POI 5.2.3 核心依赖 --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>5.2.3</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>5.2.3</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml-schemas</artifactId> <version>5.2.3</version> </dependency> </dependencies>
内容的提问来源于stack exchange,提问作者Hervé Girod

