这个DocumentImpl 的真实路径也是 JDK1.8中 rt.jar 包里面的,它是 CoreDocumentImpl 的子类,CoreDocumentImpl 是接口Document 的实现类。
package com.sun.org.apache.xerces.internal.dom; public class DocumentImpl extends CoreDocumentImpl implements DocumentTraversal, DocumentEvent, DocumentRange { ...... }CoreDocumentImpl
package com.sun.org.apache.xerces.internal.dom; public class CoreDocumentImpl extends ParentNode implements Document { ...... }我们在 CoreDocumentImpl 类中第983行发现了getXmlStandalone方法。
这时报错原因赤条条的摆在我们面前了,显而易见,DOM2TO类中 setDocumentInfo 方法的参数 Document 是属于 JDK1.8 中 rt.jar 包下类路径 com.sun.org.apache.xerces.internal.dom 下的实现类 DocumentImpl。而我们报错的信息提示中是:
Caused by: java.lang.AbstractMethodError: org.apache.xerces.dom.DocumentImpl.getXmlStandalone()Z这个 org.apache.xerces.dom.DocumentImpl 明显不属于我们 JDK1.8 的 rt.jar 包,而且也没有 getXmlStandalone 这个方法。
所以得知,我的项目中 jar 包依赖冲突了,我们只需要排除掉 org.apache.xerces.dom.DocumentImpl 所属的 jar 包就可以了。如何排除呢?
排除冲突我们在 IDEA 中双击 Shift 键,输入 DocumentImpl,得到如下结果:
可以发现,这里有两个 CoreDocumentImpl,一个是我们的 JDK1.8的,一个是属于 xerce的,而且确实在依赖的 maven jar 包中发现了 xercesImpl-2.4.0.jar,这个 jar包就是需要排除的 jar包。
发现了冲突的 jar包,我全局搜索关键字 xerces,并没有发现哪一个 pom 中有依赖的代码,所以很可能是其他的 jar 包传递依赖进来的。
我们借助 IDEA 的 maven 工具,在 maven 栏右键项目模块,选择 show Dependencies 或 Ctrl + Shift + Alt + U,这时候会展示当前模块的 jar 包依赖图,如下:
虽然这里展示了很多冲突的jar包,其中红线连接的就是冲突的jar 包,但是我们 Ctrl + F 查询 xerces 还是没有结果。
所以我们需要额外的方式来解决,这时我想到了 IDEA 有个插件 Maven Helper,具体的插件下载可以参考前面的内容,下载好插件后,我们打开 pom.xml 文件,在pom.xml 文件的左下方有个 Dependency Analyzer,我们点击之后显示如下:
Conflicts:展示所有冲突。
All Dependencies as List:以列表的方式展示所有依赖。
All Dependencies as Tree:以树形的方式展示所有依赖。
我们输入 xerces,选择以树形展示所有依赖,得到如下的信息显示。
清晰明了,原来这个罪魁祸首是被 file-web-sdk 带进来的,我们右键选择 Jump To Source或者 F4 定位到这个 jar 在 pom.xml 的依赖引入位置,如下图所示,我们通过 exclusion 标签排除 xercesImpl 的引入即可。
<dependency> <groupId>com.xx.xx.gov.fileservice</groupId> <artifactId>file-web-sdk</artifactId> <exclusions> <exclusion> <groupId>xerces</groupId> <artifactId>xercesImpl</artifactId> </exclusion> </exclusions> </dependency>再次启动项目,测试接口发现功能正常了,整个排查过程也就结束了,IDEA的功能还是很强大的。
总结