Spring AI Alibaba 的 PoiDocumentReader 把 docx 灌进向量库,跑起来直接抛异常

📅 2026/7/29 3:50:33
Spring AI Alibaba 的 PoiDocumentReader 把 docx 灌进向量库,跑起来直接抛异常
— 一次 POI 版本不一致导致的 SPI 加载异常排查记录 —一、问题现场今天用Spring AI Alibaba的PoiDocumentReader把 docx 灌进向量库跑起来直接抛异常Your InputStream was neither an OLE2 stream, nor an OOXML stream or you havent provide the poi-ooxml.jar and/or poi-scratchpad.jar in the classpath/modulepath - FileMagic: OOXMLdoc 文件毫发无损唯独 docx 报错。明明是 docx 的 OOXML 流凭啥说找不到解析器二、跟进源码报错堆栈指向org.apache.poi.extractor.ExtractorFactory#wp核心逻辑就是遍历Singleton.INSTANCE.provider找能处理当前 FileMagic 的工厂private static POITextExtractor wp(FileMagic fm, ProviderMethod fun) throws IOException { for (ExtractorProvider prov : Singleton.INSTANCE.provider) { if (prov.accepts(fm)) { POITextExtractor ext fun.create(prov); if (ext ! null) { return ext; } } } throw new IOException( Your InputStream was neither an OLE2 stream, nor an OOXML stream or you havent provide the poi-ooxml*.jar and/or poi-scratchpad*.jar in the classpath/modulepath - FileMagic: fm , providers: Singleton.INSTANCE.provider); }断点打进去一看Singleton.INSTANCE.provider这个 ArrayList 里只有两个元素OLE2ScratchpadExtractorFactoryMainExtractorFactory关键的那一个没了——负责 OOXML.docx/.xlsx/.pptx的根本没被加载进来。三、真相只有一个版本不一致POI 的这些ExtractorFactory是通过Java SPI机制加载的入口在META-INF/services/org.apache.poi.extractor.ExtractorProvider。打开 IDEA 的 Maven 依赖面板一看果然poi5.4.0poi-ooxml4.1.2← 拖后腿的Spring AI Alibaba 引入的是 5.4.0但项目里某个老依赖把poi-ooxml锁死在 4.1.2。问题来了poi 5.4.0 启动时扫描 SPI想加载OOXML的解析器但这个类的 class 文件在 4.1.2 的 jar 里5.4.0 找不到对应的实现类加载失败被吞掉ArrayList 里就只剩两个老格式工厂了docx 流进来遍历到底也没人接最后抛 IOE。四、解决方案统一版本把poi-ooxml也升级到 5.4.0dependencygroupIdorg.apache.poi/groupIdartifactIdpoi-ooxml/artifactIdversion5.4.0/version/dependency重启后Singleton.INSTANCE.provider里就能看到OOXML的解析器了docx 顺利入向量库问题解决。五、踩坑经验POI 系列必须同版本共进退poi/poi-ooxml/poi-scratchpad版本一旦不一致SPI 加载就会静默失败。遇到 SPI 加载异常先看依赖树mvn dependency:tree | grep poi一眼能看出谁在拖后腿。推荐用 BOM 统一管理Spring AI Alibaba 依赖的是 POI 5.4.0建议在父 POM 用poi.version统一锁定避免被别的传递依赖带偏。