一个让java程序员有杀人的冲动的Xerces冲突问题

摘要:
Xerces以前是发布一个jar包,但是之后分成两个jar包发布,一个包含API的xml-apis.jar和另一个包含其实现的xercesImpl.jar。许多老点儿的MavenPom仍然依赖xerces.jar。发布到Maven仓库的一些jar经常会依赖版本不同的xml-apis和xercesImpl。)使用的XML解析器就是用的这个鸟Xerces。问题Maven解决jar包冲突正是由于以上的一个或几个问题,许多组织会在他们的pom中重新构建自己的Xerces。除此之外,你还要应付servlet容器中的包含的Xerces。保留servlet中的那个版本,然后祈祷你的应用框架可以在servlet提供的Xerces版本上正常运行。

History

  • Xerces是Java生态圈使用最广泛的XML解析器,基本上所有的类库和框架都会在一定程度上使用它(即使没有直接引用,也有可能间接引用)
  • Xerces在官网中发布的包是没有标注版本的,2.11.0的jar命名为xercesImpl.jar而不是xercesImpl-2.11.0.jar.
  • Xerces不使用Maven,不会上传官方的release版本到Maven的中央仓库。
  • Xerces以前是发布一个jar包,但是之后分成两个jar包发布,一个包含API的xml-apis.jar和另一个包含其实现的xercesImpl.jar。许多老点儿的Maven Pom仍然依赖xerces.jar。更早的时候Xerces发布一个xmlParserAPIs.jar,也有些很古老很古老的pom会依赖这个jar。
  • 发布到Maven仓库的一些jar经常会依赖版本不同的xml-apis和xercesImpl。举例来说,依赖的xml-apis的版本可能是1.3.03而依赖的xercesImpl版本可能就是2.8.0,即使两个包都是来自
    Xerces 2.8.0。因为人们使用xml-apis.jar只想使用它某个版本的特定的API。
  • 更麻烦的是,JRE中JAXP(Java API for XML Processing)的Reference implementation(参考实现?)使用的XML解析器就是用的这个鸟Xerces。实现类被重新打包进了com.sun.,从而导致直接引用这些类很危险,因为他们在某些JRE中可能不会包含。然而,Xerces中并不是所有的方法都通过java.和javax.*的API暴露。举例来说,就没有实现Xerces序列化的API。
  • 基本上所有的servlet容器(JBoss, Jetty, Glassfish, Tomcat, ====),都包含一份或多份Xerces在他们的/lib包下。

问题

Maven解决jar包冲突

正是由于以上的一个或几个问题,许多组织会在他们的pom中重新构建自己的Xerces。当你的工程比较小而且你在用maven中央仓库的时候,这没什么问题。但是当你用Artifactory或者Nexus代理你的多个仓库时(JBoss的,Hibernate的,==),可能就出现问题了。

XercesJar

举例来说,A组织可能以如下方式依赖xml-apis:

<groupId>org.apache.xerces</groupId>
<artifactId>xml-apis</artifactId>
<version>2.9.1</version>

而B组织可能以如下方式依赖同样的jar包:

<groupId>xml-apis</groupId>
<artifactId>xml-apis</artifactId>
<version>1.3.04</version>

尽管B的jar版本比A的jar版本低,但是maven并不知道他们俩是同一个artifact,因为两个jar的groupId不同,那么,最后maven解决版本的冲突而是把两个jar同时引入项目。如下图:
Xerces冲突示例

类加载器Hell

上面提到的,JRE会在JAXP RI中包含Xerces。当你把maven依赖的所有的Xerces都标记成<exclusion>或者<provided>虽然看起来没什么问题,但是你依赖的第三方代码可能和你使用的JDK中的JAXP中Xerces版本不兼容。除此之外,你还要应付servlet容器中的包含的Xerces。这给了你几个选择:
  • 删除servlet中的Xerces,然后祈祷你的容器可以在JAXP提供的版本上运行。
  • 保留servlet中的那个版本,然后祈祷你的应用框架可以在servlet提供的Xerces版本上正常运行。
  • 如果最后你的产品有那么一个或者两个没解决的版本冲突(如果你的应用很大的话,这是很容易出现的情况),你很快就会发现你正处于类加载器地狱(ClassLoader Hell),疑惑类加载器到底他妈的挑了那个版本在运行?在window或者linux上会不会挑同一个版本(很有可能不会)。

解决方案?

我们尝试把所有的Xerces的maven依赖标记成 或者,但是由于这鸟货的别名太多了(xml-apis, xerces, xercesImpl, xmlParserAPIs,====),这有时候并无卵用。另外,我们依赖的第三方包或者框架很可能不会跑在JAXP的版本或者servlet容器提供的Xerces版本上。
到底怎么解决?

目前他们的解决方案如下:
可以尝试使用maven enforcer插件中的banned dependency。这个rule可以让你禁止所有你不喜欢的别名,而且只会加入你喜欢的。

免责声明:文章转载自《一个让java程序员有杀人的冲动的Xerces冲突问题》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇CentOS8安装JDK8并配置环境变量第十八节:Asp.Net Core WebApi基础总结和请求方式下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

xml解析(4)

本节要点: DOM解析方式 SAX解析方式 DOM4J对XML的解析 XML用于将数据组织起来,形成文档用于存储和传输; 更多时候我们需要的是将xml中的数据解析出来,甚至是在程序中动态生成xml。 操作xml的方式有两种DOM和SAX。 XML解析方式分为两种:DOM方式和SAX方式: DOM:Document Object Model,文档...

利用OpenXml生成Word2007文档

一、OpenXml简介 利用C#生成Word文档并非一定要利用OpenXml技术,至少可以使用微软提供的Office相关组件来编程,不过对于Office2007(确切的说是Word、Excel和PowerPoint2007)及以上版本,微软提供了这些信息组织的另外一种思路:OpenXml技术。         OpenXml是微软office2007及之后...

主题:android之XmlResourceParser类使用实例 转

http://www.iteye.com/topic/1122056 android开发过程会经常使用XML文件,下面提供小实例,看看XmlResourceParser类是怎么样解析XML文件的。 XML文件名称为test.xml。内容如下: Xml代码 <?xmlversion="1.0"encoding="utf-8"?> <...

Python源代码安全审计工具之Bandit

Bandit是一种旨在查找Python代码中常见安全问题的工具。 它处理每个文件 从中构建AST 然后针对AST节点运行适当的插件。 当它扫描完成所有文件之后将生成报告。 以下安装部署过程基于Windows操作系统,假设已经安装并设置好了以下软件。 "Python 3.7.8 AMD64" "64-bit Git for Windows" 最便捷的安装方式...

补习系列(2)-springboot mime类型处理

目标 了解http常见的mime类型定义; 如何使用springboot 处理json请求及响应; 如何使用springboot 处理 xml请求及响应; http参数的获取及文件上传下载; 如何获得原始请求的字节流; 6.了解springboot 如何实现内容转换; 一、关于MIME MIME的全称是Multipurpose Internet Mai...

使用 Spring 3 来创建 RESTful Web Services(转)

使用 Spring 3 来创建 RESTful Web Services 在 Java™ 中,您可以使用以下几种方法来创建 RESTful Web Service:使用 JSR 311(311)及其参考实现 Jersey、使用 Restlet 框架和从头开始开发。Spring 是流行的 Java EE 应用开发框架,现在它的 MVC 层也支持 RE...