时慧

时慧的博客

他的个人主页  他的博客

依赖库的版本一致性

时慧  2009年08月15日 星期六 20:55 | 2394次浏览 | 2条评论

用Maven作为build工具时,遇到了一件很奇怪的事,经研究发现,是对于依赖库的版本不一致造成的,推测了一下,应该Python的Cheeseshop(PyPi)也会有这样的问题吧

用GWT编写web前端,需要嵌入Google Maps,发现Maven(一个build工具,提供对依赖库的自动解决方案,可以参考 http://maven.apache.org,和Python的PyPi有些类似吧,但是功能非常强大,强大到无聊……)的仓库里,已经存在了,于是就写了一下pom文件,这样任何人取了我的工程,都可以自动下载需要的库,然后编译,执行就OK了。

但是奇怪的是,这个工程所生成的jar包,在tomcat运行时,总是报错,说是和Servlet API冲突了,所以没有加载,以至于其中的servlet无法被调用,造成错误。其实这个工程,我们是“抄袭”另一个工程的,那个就OK,凭什么呢?我们仔细搜索每一个可疑的角落,但是都没有什么发现,就在我们一致认为,这是我们的RPWT,想等到我们RP值恢复后再试试时,我打开了那个jar包,发现里面除了我们的代码生成的class文件外,还包含了javax/servlet的内容,怪不得会和servlet-api这个包冲突,原来是我们这个包已经珠胎暗结了。

调查原因!发现,原来我们已经在用GWT-1.7.0了,但是由于gwt-maps这个包的pom文件(可以认为是这个jar包的metadata,记载了该jar的名称以及它需要的依赖关系)里,对gwt的依赖版本是1.5.3,然后maven超智能的发现,原来我们没有提供对servlet api的依赖(因为版本不同,我们提供的是1.7.0的,它不认),于是就自作主张把需要的servlet api也打包进了最终的jar包,造成和tomcat自带的servlet api实现冲突,于是被赶出家门,没有load进tomcat里,最终终于servlet调用失败。

简而言之,就是当A需要B和C,而C呢,也需要B的时候,A需要的B是2.0的,但是C所需要的是1.0的,版本不一致了,于是千奇百怪的事就都出现了。

想想python的pypi也有这样的问题,只是好像maven对包的依赖描述中,要写清楚某个版本,但是python的,除非刻意指定,否则就会用最新版本的,这样呢,对于像TurboGears,Pylons这样的拼装起来的框架来说,说不定某一次一个升级,就运行不起来了。

这好像没有一个完美的解决方案,目前我想到的最好的方法是,设置一个可以接受的版本范围,然后让maven自动来选择一个皆大欢喜的结果,如果实在没有办法自动解决,起码也要让用户知道出问题了,然后让用户来选择到底用哪个版本,绝对不能现在这样,偷偷摸摸的自作主张,排查真的很麻烦

评论

我的评论:

发表评论

请 登录 后发表评论。还没有在Zeuux哲思注册吗?现在 注册 !
文平

回复 文平  2009年08月15日 星期六 22:16

我看TurboGears的文档,建议使用virtualenv建立一个独立的tg开发运行环境,其依赖包基本都可以在TurboGears的网站上获取到,网站上的依赖包版本是由TurboGears开发人员维护的。这样只要不随便在这个特殊环境里面随意升级、更新包,就不会有什么问题了吧?

1条回复

  • 时慧

    回复 时慧  2009年08月15日 星期六 22:20

    解决方法总是有的,但是不够通用,也有些限制,所以觉得不是很爽。像maven,我也可以修改本地仓库的设置,但是总觉得不爽,呵呵

    0条回复

暂时没有评论

Zeuux © 2024

京ICP备05028076号