数数自己经历过的几种项目构建工具
一提到项目构建, 对于Java开发人员来说, 最先跃入脑海的自然当属ANT, 所以, 就先从俺ANT的经历开始…
ANT先行
要说当年我的那个ANT用法,真的不是啥名门正派的用法,更多的是为了避免过多的重复劳动而已, 不过,这应该也算是ANT存在的一种意义吧,呵呵
当年CREDIT发行的时候采用可以单独运行的exe形式, 所以, 每次发行的时候,需要使用IntallAnywhere打包并制作安装文件, 安装文件的结构以及针对不同安装版本和环境的配置文件的准备工作, 如果每次都来一遍,会很费劲,所以,就写了个ANT脚本来做这些事情, 这样, 每次ant release之后,直接从InstallAnywhere里把构建好的安装目录结构和相关文件导入,然后点击制作安装文件就OK了 1 。
所以,你看,我的ANT经历并不是真正意义上的那种项目构建和管理经历,更多的是为了用它来简化日常的工作,至于你什么dailybuild, 集成测试啥的,那个时候(4,5年前)不上也没人说你水平菜,呵呵
Eclipse那囊括一切的宽广胸怀
如果整个项目组或者整个公司都使用Eclipse进行开发的话,那么,下面这样的过程说不定你就会感觉很熟悉了。(下面更多提及项目的依赖管理,至于项目的building以及生命周期管理之类, 略去不表吧,整个话题会不完整,所以,只是会简单提及一下)
Eclipse有自己的builder体系, 所以, 不用ANT, 直接使用Eclipse的builder体系来完成项目的构建, 管理得当,也很不错的,起码我认为是, 在那套生态体系下的生活经历让我深信不疑,呵呵
在Eclipse里管理项目的依赖关系通常有两种方式。第一种方式就是创建本地依赖库, 让各个项目直接依赖本地依赖库。 如果单人单机开发,这种方式是合适的,可一旦推广到多人多机, 那就来问题了:
- 每人的本地依赖库的具体情况可能千差万别,提交到版本控制系统(比如CVS)之后, 没有一个统一的标准, 这样,当A提交了自己的本地依赖库信息之后, B又来update依赖信息的时候, 可能就会出现B的本地没有和A相同的本地依赖库的情况, 诸如此类。
- 无法集中管理,存在冗余, 版本信息混乱, 等等…
既然第一种方式存在这些问题,那么就有了第二种方式。
第二种方式应该是很普遍的, 为了解决第一种方式中碰到的一些依赖问题, 我们通常会在新建项目的时候,同时建立一个lib目录,其中保持项目所依赖的各方类库, 这样,提交到CVS之后, 每个开发人员check到本地的项目拷贝,就会持有统一的项目依赖了。这种方式很好的解决了第一种方式中提到的第一个问题, 不过, 也并不完美:
- 所有的项目依赖将被提交到CVS等版本管理系统中,会占用很多CVS Repository空间;
- 单一项目还好说, 随着项目和模块的增多, 相同的依赖就会散落到不同的项目中, 造成CVS空间浪费不说, 依赖的存在也显得冗余;
- 针对每个依赖的各方类库没有合适的版本管理机制,比如这个项目依赖hibernate2.x,而另一个可能依赖hibernate3.x, 当合并两个项目发布的时候, 可能因为这种依赖类库详细版本信息的缺失,造成问题;
看来, 第二种方式也不完美啊, 不过,没关系,发现问题是好事儿,解决掉他们就好了!
集中式依赖管理时代
解决冗余问题一直都是我们为之奋斗的目标, 为了解决以上依赖管理过程中出现的种种问题, 我们现在要寻求一种集中式的依赖管理方式。这里面最为业界称道的当属Maven啦, 不过,我倒是乐意顺道再提及一个花旗内部使用的XENV, 它也是用来完成类似任务的。
Maven和XENV都采用集中中央依赖库的方式来管理依赖关系, 这样, 各个项目只要通过统一的依赖描述文件来指定自己需要的依赖就可以, 而不用自己来管理真正的依赖库,因为所有的项目都使用同一个中央依赖库, 所以即使各个项目中有相同的依赖, 也不会出现依赖冗余的问题。
在这里想对maven和xenv各自的特性多唠叨几句。Maven在集中式依赖管理时代属于比较典型的产品, 它不但支持传递的依赖关系管理, 而且支持本地的依赖缓存, 其它像插件化管理, profiles支持等等,整体上来说,比较成熟。 xevn属于花旗内部的一个依赖管理和项目构建环境, 这个环境以unix环境下的开发为出发点, 对项目构建的生命周期管理比较完备, 有完备的代码提交和审查机制, 不过,它没有本地的依赖缓存功能, 这在具体开发过程中会造成一定的不便,比如, 中央库的服务器和开发人员处于统一局域网内,那网络延迟还可以接受, 一旦网络跨度达到跨洲, 那网络延迟就会让基于xenv的依赖管理变得不可忍受, 这时候, 如果有本地依赖缓存库的支持,情况就会很好。 为了缓解这种情况,我看到的是,采用了eclipse中各自建立本地依赖库的方式, 至于缺点,我想就不用再说了。 另外, maven支持依赖库的版本管理,xenv没有。
ANT+IVY组合
Maven的理念和实现方式跟ANT有很大的不同, 所以, 从ANT到Maven的迁移成本还是不小的。如果你不想迁移,却依然想要享受到maven类似的中央依赖库功能,那么可以考虑ANT+IVY这一魅力组合。
IVY提供了类似Maven的中央依赖库依赖管理方式(通常是直接用Maven的某些中央依赖库),使用Ivy,你同样只需要为每个项目提供相应的依赖描述文件, 之后, Ivy将通过settings.xml的描述信息,到某个中央依赖库为你的项目抓取相应的依赖,基本上跟Maven类似的做法, 只不过, 借用了Maven的“骨肉 ”, 用ANT支撑一下, 也成了一套比较有特色的解决方案。
Spring3的构建和依赖管理采用的就是IVY+ANT的组合方式。
后话
基本上也就是些鸡毛蒜皮的回忆文字, 当初Maven1的年代,对这东西还真没啥好的印象,现在PT用Maven2来管理所有的项目构建和依赖管理, 我也只能入乡随俗了, 故此,把之前的和现在的东西扒拉一下,聚成这篇文字, 算作纪念吧!
PS. 像Make, Rake之类的, 零星玩过的就飘过吧
后后话
2014-07-26, 重新整理这篇博客到本地基于markdown格式的文本的时候, 现阶段Maven3, Gradle, SBT等构建工具更是各领风骚啊~
当然,实际上, 你也可以在Ant脚本里直接调用installAnywhere提供的命令行形式,而不启动带GUI的Installanywhere进程,这样,直接一条命令全部搞定。↩︎
「福强私学」来一个?
「福强私学」, 一部沉淀了个人成长、技术与架构、组织与管理以及商业上的方法与心法的百科全书。
开天窗,拉认知,订阅「福报」,即刻拥有自己的全模态人工智能。