关于Jar包的管理,你有什么想说的吗

金贞花 发布于 2014/02/12 15:23
阅读 1K+
收藏 1

对于做Java的同学而言,应用依赖的那一众的Jar如何管理是个大难题,像我们的很多应用动不动就依赖上百个Jar,这些Jar的冲突问题很容易 导致各种奇怪现象,例如有些机器是OK的,有些机器却报NoSuchMethodException等等,说说Jar管理中要解决的几个问题以及现在我们 的解决方法,另外就是也希望能听到大家对这块的建议或者碰到过的问题。

Jar管理中最容易碰到的是这么几个问题:
1. Jar包版本冲突
这是最容易出现的现象,因为应用引用的Jar可能会再依赖其他的Jar,于是这种情况下会变得很不可控,通常来说用maven管理的java工程,在打包 的时候会检查同样groupId和artifactId的依赖有没有出现版本冲突的现象,如果出现会禁止打包,这一定程度上缓解了依赖冲突的问题。

不知道大家碰到过多少那种改了groupId或artifactId,但里面类的包名什么的又没变的现象,反正我是碰过很多次了,对于这种状况Maven 是提供不了什么帮助的,这种状况被发现通常会是由于应用启动或运行的时候报ClassNotFoundException或 NoSuchMethodException,在启动参数上增加-XX:+TraceClassLoading有可能就会发现原来加载到了另外一个 Jar,最龌龊的现象是某些jar把它依赖的jar的类也打包进去了。

Jar包版本冲突的问题绝对是Java应用不好解决的一个点,通常这类问题目前会采用这样一些方法来避免:
* 在pom.xml中写依赖的时候exclude掉依赖的某些依赖,避免依赖的依赖带来jar冲突;
* 对于实在找不出有冲突的jar是哪里造成的时候(至少我确实碰到过,即使用mvn dependency:tree也没找到),可以在pom.xml中直接写不想打入包中的那个jar的依赖,scope指定为provided,这样可以 实现强制不把这个版本的jar打入包中;
* 在打包完成后,解开所有的jar,检查是否有完全同样的类名但类文件内容又不一致的现象,如果有则报错等,这种需要编写一个小的mvn插件来完成,或者也 可以在一个打包脚本中最后用脚本来解决,这种千万不能存在侥幸心理,什么自己机器上是OK的,只要有类版本冲突,就是有可能会出现问题的,之所以在你的机 器不出现只是可能凑巧装载的class是你应用需要的那个。

还有一类Jar包版本冲突问题可能是你的应用和容器的冲突,例如在jboss/tomcat里,尽管通常jboss/tomcat会提供 classloader隔离的机制,但很多时候会出于某些需要关闭,这种时候就很容易导致容器的jar和应用的jar冲突的现象,这种是最不好搞的,因为 只能是覆盖容器的。

ps: 真心希望Java能从语言级更好的解决依赖的问题,否则对于大型应用工程而言,Jar的冲突始终是个不太好处理的问题。

2. SnapShot包的问题
你的生产环境里跑的应用里依赖了多少SnapShot的包呢?这种是很容易造成极高的风险的,因为通常SnapShot的依赖在打包时会直接升级成最新的,而最新的这种有可能是有问题的,如果就这样打包后部署到生产环境,有可能会产生悲催的故障。
前两天我们在发布的时候就碰到过一次这个问题…
我们之前为了避免这类问题,是在打包的时候会检查是否有SnapShot的版本,有的话会禁止打包,但据说后来由于此类依赖太多,就去掉了,但从我们上面碰到的问题可以看到,这种问题是相当严重的…

3. 依赖了老的有bug的版本的Jar的问题
应用里依赖的无论是外部提供的Jar,还是公司内部其他团队提供的Jar,都有可能依赖的是有bug的版本,碰到这样的现象该怎么统一控制呢? 例如发邮件通知所有的开发,某个版本不能用? 通常来说这种通知都是无效的。
我们对于此类问题是写了一个maven插件,在打包时会增加一个依赖的jar包规则,例如当依赖的某个jar时,必须高于某版本,或不等于某版本,如果不符合的话则拒绝打包。
这个方法对一些需要升级jar版本的场景也会有帮助,例如提供的一个老版本的jar,可能希望在3个月后接口全部升级到新接口,于是可以在打包的时候提醒依赖的某个老版本的jar在几个月后会废弃,这样通常对升级会有一些帮助。

关于Jar包的管理,你有什么想说的吗,欢迎回复消息。



from:http://hellojava.info/?p=156#comment-214

加载中
0
Brin想写程序
Brin想写程序
重复制造轮子可破。
金贞花
金贞花
回复 @Brin想写程序 : (⊙v⊙)嗯
Brin想写程序
Brin想写程序
回复 @Gelopa : jar问题,在有java的第一天开始大家就知道了。在开发C++的时候,还有dll噩梦一说,这比java要早很多。 dll跟jar没区别。既然想省事,必须付出代价啊。 如果作为一个公司,想长期延续的在技术上不断发展,搞自己的库肯定是必然之路啊。就像阿里,淘宝,百度一样的。 小公司就尽量的少依赖框架吧。
金贞花
金贞花
回复 @Brin想写程序 : 这个量很大吧
Brin想写程序
Brin想写程序
回复 @Gelopa : 无耻一点,把用到源代码拆出来,变成自己的包。大家就依赖一个包。参考google的guava
金贞花
金贞花
你怎么想
0
Carvendy
Carvendy

楼主不知道,你有没有遇到和我一样的问题。就是在写maven插件的时候,插件发布后,不能读取插件本身的properties文件。

返回顶部
顶部