轉(zhuǎn)自:http://carllgc.blog.ccidnet.com/blog-htm-do-showone-uid-4092-type-blog-itemid-263093.html
作為一位Java程序員,如果您沒有接觸過開源軟件、項目或框架的話,恐怕有些不可思議。轟轟烈烈的開源運動起源于Linux操作系統(tǒng),Apache基金會在其中扮演了中流砥柱的角色,業(yè)界巨擘SUN,IBM, BEA 和Oracle等公司的積極參與,使得聲勢浩大的開源運動成為軟件開發(fā)領(lǐng)域勢不可擋的力量。2001年11月,IBM向Apache基金會捐獻出Visual Age for Java,這個看似窮途末路的產(chǎn)品經(jīng)眾多高手的改造,演變?yōu)檩x煌一時的Eclipse,直接擊敗了不開源的JBuilder,讓做編譯器起家的Borland公司幾乎關(guān)張大吉。Eclipse這個產(chǎn)品如此經(jīng)典,以至于微軟的Visual Studio都得向它學(xué)習。在Apache Harmony的圍追堵截下,Java的發(fā)明者Sun公司一看勢頭不妙,于2006年宣布Java開源,隨后又公開了其旗艦級產(chǎn)品Solaris的源代碼。今年1月,開源的死對頭、冷酷自私的微軟也不得不在MS-RL協(xié)議下公開.Net的源代碼。但是,在這如火如荼的開源運動中,我們中國的程序員又有多少貢獻呢,我們開創(chuàng)了哪些框架、項目和產(chǎn)品,為開源界添磚加瓦呢?以筆者短淺的目光看來,我們對開源界貢獻的東西恐怕很少,能夠與國外經(jīng)典開源項目一較高下的,少之又少矣! 作為一名中國的程序員,咱們能沒有遺憾嗎?為什么經(jīng)典的Apache Web Server不是中國人寫的;為什么Linus Torvalds在大學(xué)時代就寫出Linux并振臂一呼,應(yīng)者云集;為什么JBoss能與巨無霸式的Websphere相抗衡;為什么MySQL能在Oracle和SQL Server的夾擊下發(fā)展并壯大…… ?如此等等問題,在遺憾之余,我想我們應(yīng)該花點時間好好思考一下,中國的軟件產(chǎn)業(yè)怎么了,中國的程序員又怎么啦? 在筆者看來,我們的程序員對開源的理解是相當狹隘的。國學(xué)大師王國維曾說過,古往今來成大學(xué)問大事業(yè)者要經(jīng)歷三種境界,“昨夜西風凋碧樹,獨上高樓,望盡天涯路”,這是第一重境界,迷惘也;“衣帶漸寬終不悔,為伊消得人憔悴”,苦苦求索之境界也;第三重境界為“眾里尋他千百度,驀然回首,那人卻在燈火闌珊處”,經(jīng)歷多少次的失敗和挫折后,終于參透真諦,領(lǐng)悟真理。我覺得開源也有三重境界: 首先,我們要敞開心胸,擁抱開源(Open to Open Source)。這重境界我們大家都能做到,拿來主義嘛,誰人不會。當我們的項目需要數(shù)據(jù)庫時,就去下載一個免費MySQL;需要IDE時,去下載 Eclipse;需要版本控制工具時,就去下載CVS;需要寫搜索引擎時,Lucene可能是我們的最愛;當我們開發(fā)J2EE Web應(yīng)用時,Struts/JSF加Hibernate/iBATIS再加上Spring或許成為我們的首選架構(gòu)。但是,我們絕大部分程序員都停留在這 個層次上,大家下載之后,看看文檔介紹,安裝、配置并能運行,就以為萬事大吉,一切順利。偶爾遇到一些問題,去Google一搜,答案立馬可得。 其次,我們要深入開源,了解開源(Dig into Open Source)。要達到這個層次,就有些難度了。我們不但要知其然,還要知其所以然。“知其所以然”的最好辦法就是下載源代碼,仔細研讀,揣摩并領(lǐng)會源代 碼的精義,看看這些經(jīng)過諸多高手修改的源代碼究竟藏有什么玄機,我們能從其中學(xué)習到哪些設(shè)計思想及設(shè)計模式,能復(fù)用其中哪些源代碼,人家運用了哪些軟件管 理思想把這些來自世界各地程序員的勞動匯集成一個產(chǎn)品,代碼架構(gòu)如何,軟件配置管理又是怎樣進行的……,等等等等,我們從源代碼中學(xué)習的東西太多了。在閱 讀源代碼時,我們要多問自己幾個為什么,這樣就會收獲更多。 再次,我們要融入開源,貢獻開源(Get involved in Open Source)。當我們徹底理解該項目源代碼后,我們應(yīng)發(fā)揮一下“人人為我,我為人人”的思想,或結(jié)合您的實際需要,或結(jié)合您的新想法,或針對Mail lists上的問題,對該開源項目加以改進和創(chuàng)新,并把自己的代碼貢獻出來,讓大家評估。當然,如果您有好的想法,您完全可以創(chuàng)建自己的開源項 目,Apache基金會中眾多的開源項目不都是我們廣大程序員一手創(chuàng)建的嗎?但是,在創(chuàng)建新開源項目時,切忌不要重新發(fā)明輪子。 筆者才疏學(xué)淺,想以Apache Jakarta項目包中的核心項目Tomcat為例,希望通過閱讀源碼,能從這個經(jīng)典項目中學(xué)到更多的東西,為我們中國的開源事業(yè)起到拋磚引玉的作用。 下面我們就開始我們的Tomcat源碼學(xué)習之旅。 1. 下載Tomcat6.0的源代碼 首先,我們得下載Tomcat6.0的源代碼。Tomcat源代碼的版本控制工具不是CVS,而是Subversion,如果您的機器上沒有安裝Subversion,請從 http://subversion.tigris.org/servlets/ProjectDocumentList?folderID=91 下載并安裝這個開源的版本控制工具。當然,如果您想從Eclipse中直接導(dǎo)入Tomcat源代碼,請從http://subclipse.tigris.org/update_1.0.x下載Subversion插件,即可導(dǎo)入Tomcat源代碼。安裝完成后,請在MS-DOS窗口中鍵入svn export help,您將會看到: C:\Documents and Settings\carlwu>svn help export export: 產(chǎn)生一個無版本控制的目錄樹副本。 用法: 1、export [-r REV] URL[@PEGREV] [PATH] 2、export [-r REV] PATH1[@PEGREV] [PATH2] 1、從 URL 指定的倉庫,導(dǎo)出一個干凈的目錄樹到 PATH。如果有指定 REV 的話,內(nèi)容即為該版本的,否則就是 HEAD 版本。如果 PATH 被省略的話,URL的最后部份會被用來當成本地的目錄名稱。 2、在工作副本中,從指定的 PATH1 導(dǎo)出一個干凈的目錄樹到 PATH2。如果 有指定 REV 的話,會從指定的版本導(dǎo)出,否則從工作副本導(dǎo)出。如果 PATH2 被省略的話,PATH1 的最后部份會被用來當成本地的目錄名稱。 如果沒有指定 REV 的話,所有的本地修改都保留,但是未納入版本控制 的文件不會被復(fù)制。 如果指定了 PEGREV ,將從指定的版本本開始查找。 有效選項:。。。。。。 我們看到Subversion給我們提供了非常友好的幫助,并且是中文的,看來中國程序員對這個開源項目有所貢獻。接下來,請在MS-DOS下鍵入: svn export http://svn.apache.org/repos/asf/tomcat/tc6.0.x/tags/TOMCAT_6_0_0/ D:\carl_wu\tomcat\src\ 這個命令的意思是把Tomcat6.0的源代碼從Subversion庫中導(dǎo)入到本機的D:\carl_wu\tomcat\src\目錄,命令運行后,您稍等幾分鐘,就會看到Tomcat的源代碼順利導(dǎo)入到目標目錄。下面是源代碼的目錄機構(gòu),從這個目錄結(jié)構(gòu)中,我們可以看出該項目的開發(fā)者使用的IDE是Eclipse,因為我們看到了熟悉的.project及.classpath文件。如果您打算開發(fā)一個Stand alone的Java應(yīng)用程序,不妨借鑒一下Tomcat的目錄結(jié)構(gòu),把腳本文件放在bin目錄,將xml和properties配置文件放在conf目錄中,把Java源碼文件放在java或者src目錄中,資源文件比如說圖片文件,ini文件及其它的一些靜態(tài)資源文件可以放在res目錄,測試源代碼可以放在test目錄中。這是一個典型的Java應(yīng)用程序的目錄機構(gòu),筆者以前曾接觸到一個來自美國的產(chǎn)品,其源代碼目錄結(jié)構(gòu)和Tomcat及其相像。 2. 編譯并運行 代碼下載后,我們接下來就是要編譯并運行Tomcat。一提編譯,我們不禁會想到可愛的Ant。不錯,Tomcat正是以Ant作為編譯工具,如果您還沒有安裝,請從http://ant.apache.org/bindownload.cgi 處下載并安裝它。然后,請從Tomcat的源代碼文件找到build.properties.default文件,并將該文件復(fù)制到build.properties,然后打開build.properties,找到下面這行: base.path=/usr/share/java 將它改為: base.path= D:/carl_wu/tomcat/share 在Tomcat編譯過程中,Ant會讓我們下載一些必要的依賴項目,base.path目錄就是用來保存這些項目文件的,我們可以將這個屬性指向一個已經(jīng)存在的目錄。修改完base.path后,我們回到MS-DOS窗口,切換到Tomcat源代碼所在目錄,然后運行ant download命令,如下圖所示: 一分鐘未到,Ant就告訴我們一個錯誤并提示我們編譯失敗,具體錯誤信息如下: downloadzip: [get] Getting: http://sunsite.informatik.rwth-aachen.de/eclipse/downloads/drops/R-3.2-200606291905/eclipse-JDT-3.2.zip [get] To: D:\carl_wu\tomcat\share\file.zip [get] Error opening connection java.io.FileNotFoundException: http://sunsite.informatik.rwth-aachen.de:3080/eclipse/downloads/drops/R-3.2-200606291905/eclipse-JDT-3.2.zip [get] Error opening connection java.io.FileNotFoundException: http://sunsite.informatik.rwth-aachen.de:3080/eclipse/downloads/drops/R-3.2-200606291905/eclipse-JDT-3.2.zip [get] Error opening connection java.io.FileNotFoundException: http://sunsite.informatik.rwth-aachen.de:3080/eclipse/downloads/drops/R-3.2-200606291905/eclipse-JDT-3.2.zip [get] Can't get http://sunsite.informatik.rwth-aachen.de/eclipse/downloads/drops/R-3.2-200606291905/eclipse-JDT-3.2.zip to D:\carl_wu\tomcat\share\file.zip BUILD FAILED D:\carl_wu\tomcat\src\build.xml:554: The following error occurred while executing this line: D:\carl_wu\tomcat\src\build.xml:514: Can't get http://sunsite.informatik.rwth-aachen.de/eclipse/downloads/drops/R-3.2-200606291905/eclipse-JDT-3.2.zip to D:\carl_wu\tomcat\share\file.zip Total time: 41 seconds 這個編譯錯誤非常簡單,就是找不到http://sunsite.informatik.rwth-aachen.de/eclipse/downloads/drops/R-3.2-200606291905/eclipse-JDT-3.2.zip 文件。有人可能會想,Tomcat的編譯和Eclipse的JDT有什么關(guān)系?其實不然,Tomcat是在Eclipse下開發(fā)的,所以需要Eclipse的JDT(Java Development tooling)插件來編譯Tomat源代碼。既然找不到,我們只好自己動手,上Google一搜,馬上發(fā)現(xiàn)這個文件的有效下載地址為:http://mirror.calvin.edu/eclipse/downloads/drops/R-3.2-200606291905/eclipse-JDT-3.2.zip。我們打開剛才的build.properties文件,將其34行修改為: jdt.loc= http://mirror.calvin.edu/eclipse/downloads/drops/R-3.2-200606291905/eclipse-JDT-3.2.zip 修改保存build.properties文件后,重新開始ant download任務(wù)。這次我們等的時間較長,因為eclipse-JDT-3.2.zip大約有19M,下載需要一段時間。我們可乘此機會去泡杯茶弄點咖啡什么的,等我們品茶回來,發(fā)現(xiàn)敬業(yè)的螞蟻Ant告訴我們編譯成功,雖然編譯器給出幾個警告。這時我們可發(fā)現(xiàn)剛才創(chuàng)建的base.path目錄(D:\carl_wu\tomcat\share)中已經(jīng)下載了6個依賴項目,它們都是Tomcat編譯所必須的。 下面就開始真正的編譯任務(wù)了,請在MS-DOS窗口內(nèi)鍵入ant并回車,Ant將在2分鐘內(nèi)編譯1000多個源文件并將Tomcat部署到output目錄。編譯順利完成后,請打開Tomcat的源代碼目錄,會發(fā)現(xiàn)多了一個output目錄,這是Ant的編譯后的輸出目錄。請打開Tomcat源代碼的output\build\bin子目錄,雙擊startup.bat文件,我們即可成功啟動Tomcat6.0,此時我們的編譯工作就算順利完成了。 3. 導(dǎo)入源代碼到Eclipse 3.1 請打開Eclipse,新建一個Java項目,然后點擊“Next”按鈕,請選擇“Create project from existing source”, 并在Directory文本框內(nèi)填入我們剛才下載的Tomcat源代碼目錄(i.e. D:\carl_wu\tomcat\src),然后點擊“Next”直至結(jié)束。 3.2 我們將會看到Eclipse拒絕編譯,這是因為Eclipse找不到該項目指定的庫文件。請右擊該項目,在彈出菜單中選擇“Properties”à“Libraries”,然后刪除兩個以TOMCAT_LIBS開頭的兩個庫文件,只保留一個JRE庫文件,然后點擊“OK”按鈕,這時Eclipse開始編譯Tomcat源代碼,但是發(fā)現(xiàn)一堆錯誤,這是因為我們沒有為該項目添加編譯所必須的Jar包。 3.3 準備好Tomcat項目所必須的jar文件,其實,剛才我們運行ant download任務(wù)時,已經(jīng)下載過這些jar文件包。 ant.jar (請在ant安裝目錄的lib子目錄中拷貝) commons-collections-3.1.jar (從剛才Ant下載的commons-collections-3.1子目錄中拷貝) commons-dbcp-1.2.1.jar(從剛才Ant下載的commons-dbcp-1.2.1子目錄中拷貝) commons-logging-1.1.jar(如果您本機沒有這個jar包,請從http://commons.apache.org/downloads/download_logging.cgi處下載) commons-pool-1.2.jar(從剛才Ant下載的commons-pool-1.2子目錄中拷貝) org.eclipse.jdt.core_3.2.0.v_671.jar(從剛才Ant下載的eclipse\plugins子目錄中拷貝) 3.4 當我們準備好這些jar文件后,將這些文件拷貝到某一目錄(比如說D:\carl_wu\tomcat\tomcat_lib目錄),然后在Eclipse中新建一個User Libraries,我們將這個新建的User Libraries命名為TOMCAT_LIBS,并把這些文件加到TOMCAT_LIBS。然后將我們新建的TOMCAT_LIBS添加到Tomcat6項目。另外,別忘了把JUnit庫也加到Tomcat6項目。這時Eclipse開始重新編譯,編譯過程順利通過,所有錯誤均消失,此時Tomcat6項目的目錄結(jié)構(gòu)如下: 還有,請把test目錄也加入到源代碼中,方法是在Eclipse中右擊”test”目錄,然后在彈出菜單中選擇“Build path”à”Use as Source Folder”,之后我們會看到test目錄上就多了個源代碼的符號,如上圖所示。 3.5在Eclipse中運行Tomcat。請找到Tomcat的啟動主類org.apache.catalina.startup.Bootstrap,右擊這個類,在彈出菜單中選擇“Run As…”à”Open Run Dialog…”,然后在彈出的“Run”窗口中填入程序運行參數(shù)“start”和JVM運行參數(shù)catalina.home,如下面窗口所示: 然后點擊“Run”按鈕,我們將會看到Tomcat正常啟動。恭喜,咱們的Tomcat源碼已經(jīng)成功導(dǎo)入Eclipse,這時,可視化的UML分析工具及Debug工具就能派上用場了。 3.5 調(diào)試Tomcat,請打開org.apache.jasper.compiler.Compiler類的源代碼,在generateJava()方法的第一行打一個斷點,然后在Eclipse的調(diào)試狀態(tài)下運行Tomcat,等Tomcat運行后,打開我們的瀏覽器,在地址欄中輸入http://localhost:8080/examples/jsp/jsp2/el/basic-comparisons.jsp并回車,然后我們可觀察到Eclipse此時切換至調(diào)試視圖: 上面的小實驗表明我們可以在Eclipse中通過Debugger觀察Tomcat的內(nèi)部運行機理。另外補充一點,上面的generateJava方法是將jsp動態(tài)編譯至java class,這個方法只是在第一次請求或者Jsp源碼發(fā)生變化時執(zhí)行,如果您再次在瀏覽器中發(fā)送同樣的請求,您將看不到上圖的Debug界面,因為該方法不再執(zhí)行。 另外,還有一點很有意思。Tomcat6以前版本的源代碼分散在好幾個子項目中,他們分別叫做jakarta-servletapi-5,jakarta-tomcat-5,jakarta-tomcat-catalina,jakarta-tomcat-connectors和jakarta-tomcat-jasper,我覺得Tomcat的開發(fā)者可能嫌這樣做太麻煩了,所以Tomcat6版本中將這些子項目都合并在一起了。但是,這種做法不利于我們閱讀理解源代碼
posted on 2009-06-17 18:07 石頭@ 閱讀(4375) 評論(0) 編輯 收藏 所屬分類: 基礎(chǔ)技術(shù)
Powered by: BlogJava Copyright © 石頭@