構(gòu)建一個(gè)項(xiàng)目,是一件極其復(fù)雜的事情。尤其是那種非常復(fù)雜的工程。
拿Java來(lái)說(shuō),構(gòu)建一個(gè)項(xiàng)目的問(wèn)題有一下這么幾個(gè):
- 項(xiàng)目的組織方式
- 項(xiàng)目的源代碼控制策略
- 項(xiàng)目的依賴控制(工程之間的依賴以及第三方庫(kù)的依賴)
- 項(xiàng)目的構(gòu)建方式
- 項(xiàng)目的構(gòu)建和發(fā)布周期
現(xiàn)在,有一些人還是在使用IDE來(lái)進(jìn)行項(xiàng)目的配置管理的,它的缺點(diǎn)是什么呢?
- 一般的IDE都擁有項(xiàng)目組織的功能。但是,可惜的是。IDE自帶的項(xiàng)目組織功能往往比較弱,IDE采取的項(xiàng)目組織方式都是平行式的,沒(méi)有項(xiàng)目的層次感,必須通過(guò)逐級(jí)命名來(lái)體現(xiàn),比如foo項(xiàng)目下,有兩個(gè)子項(xiàng)目,于是分別命名為foo.bar和foo.demo,同理再深一層為foo.bar.web等,項(xiàng)目完全平行化管理(結(jié)構(gòu)未必一定是平行的,但是對(duì)于IDE而言,它們是平等的)
- 現(xiàn)在流行的IDE對(duì)源代碼控制工具都有非常不錯(cuò)的支持
- IDE對(duì)同一個(gè)工作區(qū)里的項(xiàng)目依賴的控制作的非常不錯(cuò),但是形式相對(duì)單一
- 一般都是采用IDE自行手工構(gòu)建,某些IDE可以給你提供Ant腳本(比如NetBeans),如果采用復(fù)雜的構(gòu)建策略,那么要做很多手工的操作
- 沒(méi)法實(shí)現(xiàn)自動(dòng)化構(gòu)建,隨著項(xiàng)目的增大,構(gòu)建成本越來(lái)越大,構(gòu)建和發(fā)布周期傾向于延長(zhǎng)
現(xiàn)在,大多數(shù)的Java開發(fā)人員都采取了使用Ant腳本進(jìn)行構(gòu)建的方式。因?yàn)锳nt腳本:
- 不會(huì)影響你的項(xiàng)目的組織方式,你可以隨意的按照任何方式組織你的項(xiàng)目
- Ant對(duì)源代碼控制工具有很好的支持
- Ant可以明確的管理和控制項(xiàng)目的依賴,通過(guò)Ivy可以自動(dòng)下載項(xiàng)目依賴
- 自動(dòng)化批處理的方式
- 支持構(gòu)建服務(wù)器,可以實(shí)現(xiàn)每日構(gòu)建
但是,Ant腳本也不是一點(diǎn)兒?jiǎn)栴}也沒(méi)有。首先,Ant腳本的重用性不好。一般意義上的Ant腳本重用,就是Copy&Paste。Ant對(duì)此沒(méi)有什么封裝。其次,Ant使用起來(lái)也比較困難,XML格式的腳本不是十分的好寫(有了Eclipse支持以后,強(qiáng)了很多),作為腳本語(yǔ)言,Ant非常的不完善(連字符串處理的功能都非常弱,這一點(diǎn)Ant-Contrib提供了一些好一點(diǎn)兒的支持)。Ant的擴(kuò)展機(jī)制完全基于Java,不能做到即時(shí)修改。
除了Ant,在Java中,還可以采用Maven進(jìn)行項(xiàng)目的構(gòu)建。Maven項(xiàng)目是一個(gè)非常出色的項(xiàng)目。首先,它體現(xiàn)了Apache資深開發(fā)人員的項(xiàng)目組織和管理智慧。另外,它以統(tǒng)一有效的方式實(shí)現(xiàn)了項(xiàng)目的整個(gè)構(gòu)建生命周期。Maven的黑盒化操作也給項(xiàng)目的配置管理減輕了負(fù)擔(dān)。如果采用了Maven的話,項(xiàng)目的組織方式、項(xiàng)目的構(gòu)建方式、項(xiàng)目的發(fā)布控制全部迎刃而解。而且你所作的擴(kuò)展,也是以插件的方式來(lái)透明化的起作用的。重用性比Ant高很多。使用起來(lái)也非常簡(jiǎn)便。
但是,Maven也并不是沒(méi)有缺點(diǎn)。首先,Maven的項(xiàng)目組織方式是固定的,雖然這種固定的方式確實(shí)非常有道理。但是,如果與現(xiàn)有項(xiàng)目不兼容或者與IDE的項(xiàng)目組織方式不兼容的話,那么就完全不起作用了。比如Eclipse的Plugin項(xiàng)目,PDE的項(xiàng)目組織格式就與Maven2的項(xiàng)目格式完全不兼容。而且,Maven2自身的Manifest文件生成功能比較弱,對(duì)于OSGI項(xiàng)目而言,根本沒(méi)有可用性(因?yàn)橐斐芍貜?fù)工作)。由于Maven采用的是黑盒操作方式。操作不透明。你如果想作一些簡(jiǎn)單的自定義操作,也必須寫一個(gè)Maven的插件。插件的測(cè)試、調(diào)試和修改都要比Ant困難得多。
那么有什么好辦法呢?我推薦采用Ruby。
首先,Ruby是一種腳本語(yǔ)言,支持的環(huán)境有很多,而且還可以采用JRuby來(lái)運(yùn)行。而且,Ruby支持一個(gè)類似Make語(yǔ)法的腳本語(yǔ)言,那就是Rake。
Rake腳本其實(shí)就是標(biāo)準(zhǔn)的Ruby腳本,擁有所有Ruby擁有的特性(面向?qū)ο蟮龋6鳵uby也有非常好的依賴控制系統(tǒng)Gem(我個(gè)人認(rèn)為比目前的Maven的依賴控制系統(tǒng)要好)。由于Ruby是標(biāo)準(zhǔn)的解釋型語(yǔ)言,所以操作都是非常透明的,也可以做到即時(shí)修改的效果。所以,用來(lái)作構(gòu)建腳本是非常合適的。
但是,怎么用它來(lái)構(gòu)建Java項(xiàng)目呢?現(xiàn)在已經(jīng)存在一個(gè)基于Rake的Java構(gòu)建系統(tǒng)了,那就是:Raven。
Raven除了提供一些處理Java的Rake Task之外,它還提供了對(duì)Maven Repository的Gem封裝,這樣,你就可以采用Gem的方式來(lái)獲取Java的項(xiàng)目依賴了。
Rake是我所看到的第一個(gè)用面向?qū)ο笳Z(yǔ)言來(lái)寫構(gòu)建腳本的。但是,它也并不是完全沒(méi)有缺點(diǎn)的,對(duì)Java的支持太少,就是一個(gè)很討厭的缺點(diǎn)。
如果想要采用Rake,而且還要做到象Maven那樣好,那么至少要有以下幾個(gè)功能(除去Raven已經(jīng)提供的功能):
- 新項(xiàng)目的Archetype功能
- Java項(xiàng)目構(gòu)建生命周期模型
- IDE支持
- 根據(jù)源信息生成項(xiàng)目信息網(wǎng)站
目前我能想到的辦法只有一個(gè),就是自己寫(呵呵)。大家有什么高見(jiàn)?