关于maven中pom依赖冲突问题记录

一、场景

最近需要开发一个word 报告设计和展示功能模块,决定采用poi-tl 开源框架,引用集成该pom依赖后出现问题。

二、问题分析

根据poi-tl 官方文档说明:

https://deepoove.com/poi-tl/#_maven

添加依赖

<dependency>

<groupId>com.deepoove</groupId>

<artifactId>poi-tl</artifactId>

<version>1.12.2</version>

</dependency>

后执行demo 代码,生成word 文档报错如下:

org.springframework.web.util.NestedServletException: Handler dispatch failed; nested exception is java.lang.NoSuchMethodError: 'org.apache.poi.xwpf.usermodel.XWPFComments org.apache.poi.xwpf.usermodel.XWPFDocument.getDocComments()'

官网中最后的常见问题说明,此种问题一般都是poi 版本冲突,其框架依赖版本为apache-poi版本是5.2.2+

于是开始排查pom 依赖冲突,关于这个之前一直没有去认真研究,有时候解决了冲突,有时候是别人帮忙最后解决的。

这次周末一个人在办公室花时间来调试,刚开始一直以为是和easyExcel 这个依赖冲突了,但是实际上,这个只是在通用模块里面做了声明,自己调试的服务并没有直接依赖。

通过咨询大模型,其提供的方式是要在服务模块的pom.xml 中强制声明需要的依赖版本,于是做了如下处理:

复制代码
<poi.version>5.2.5</poi.version>
复制代码
<!-- 统一指定 Apache POI 版本 -->
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>${poi.version}</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>${poi.version}</version>
</dependency>

这样运行后,再次调用接口,报错如下:

org.springframework.web.util.NestedServletException: Handler dispatch failed; nested exception is java.lang.NoClassDefFoundError: org/apache/commons/io/output/UnsynchronizedByteArrayOutputStream

看起来又是commons-io 版本有问题,不过这个貌似不是版本冲突,而是版本太低了,可能poi-tl 中依赖的版本是比较高的,调用了一些高版本的方法,后面调试陆续还遇到如下错误:

org.springframework.web.util.NestedServletException: Handler dispatch failed; nested exception is java.lang.NoSuchMethodError: 'org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream$Builder org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream.builder()'

Caused by: java.lang.NoSuchMethodError: 'void org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream.putArchiveEntry(org.apache.commons.compress.archivers.zip.ZipArchiveEntry)'

于是根据大模型提供的方式,将commons-io 和 commons-compress 版本改为对应较高的版本,最终接口成功调用。

其实这样改完正常运行之后,在idea 的pom 依赖检查界面中还是能看到一些模块的冲突版本,刚开始我以为都要一个个exclude掉,后来调试发现将这些排除去掉也是可以正常运行的。说明pom中定义的强制版本已经生效,这里面只是间接依赖导致的,IDEA 就会标注出一个"潜在冲突"提示。

三、总结

核心原理:Maven 依赖冲突规则

先明确 Maven 解决冲突的默认逻辑,避免无效操作:

  1. 路径最短优先 :直接依赖(项目 pom.xml 显式声明)优先级高于间接依赖(依赖的依赖)。
  2. 声明顺序优先 :路径长度相同时,pom.xml 中声明在前的依赖生效。
  3. 版本锁定优先 :通过 <dependencyManagement> 声明的版本会覆盖其他版本(推荐用这种方式统一版本)。

冲突本质:多个依赖传递引入了同一依赖的不同版本 ,导致类加载异常(如 ClassNotFoundExceptionNoSuchMethodError)。

除了idea 中的插件查看外,其实也可以通过mvn 命令来查看,但是要注意setting 配置文件将自己本地的私有仓库路径配置对,不然用默认的可能会报错。

/mvn dependency:tree -Dincludes=commons-io

其实还有疑惑就是,为啥引用了poi-tl 1.12版本,看了其源码中对poi 的依赖是5.2.2

为啥业务服务中看到的依赖还是4.2 版本...

相关推荐
inferno2 小时前
Maven基础(二)
java·开发语言·maven
陈果然DeepVersion3 小时前
Java大厂面试真题:Spring Boot+Kafka+AI智能客服场景全流程解析(十)
java·spring boot·ai·kafka·面试题·向量数据库·rag
但要及时清醒4 小时前
ArrayList和LinkedList
java·开发语言
一叶飘零_sweeeet4 小时前
从测试小白到高手:JUnit 5 核心注解 @BeforeEach 与 @AfterEach 的实战指南
java·junit
摇滚侠4 小时前
Spring Boot3零基础教程,Reactive-Stream 四大核心组件,笔记106
java·spring boot·笔记
Z3r4y4 小时前
【代码审计】RuoYi-3.0 三处安全问题分析
java·web安全·代码审计·ruoyi-3.0
与遨游于天地5 小时前
Spring解决循环依赖实际就是用了个递归
java·后端·spring
陈果然DeepVersion5 小时前
Java大厂面试真题:Spring Boot+微服务+AI智能客服三轮技术拷问实录(六)
java·spring boot·redis·微服务·面试题·rag·ai智能客服