源码分析
作为一位Java程序员,如果您没有接触过开源软件、项目或框架的话 , 恐怕有些不可思议 。轰轰烈烈的开源运动起源于Linux操作系统,基金会在其中扮演了中流砥柱的角色 , 业界巨擘SUN , IBM,BEA 和等公司的积极参与,使得声势浩大的开源运动成为软件开发领域势不可挡的力量 。2001年11月 , IBM向基金会捐献出 Age for Java,这个看似穷途末路的产品经众多高手的改造 , 演变为辉煌一时的 , 直接击败了不开源的 , 让做编译器起家的公司几乎关张大吉 。这个产品如此经典,以至于微软的 都得向它学习 。在 的围追堵截下,Java的发明者Sun公司一看势头不妙 , 于2006年宣布Java开源,随后又公开了其旗舰级产品的源代码 。今年1月,开源的死对头、冷酷自私的微软也不得不在MS-RL协议下公开.Net的源代码 。但是 , 在这如火如荼的开源运动中,我们中国的程序员又有多少贡献呢,我们开创了哪些框架、项目和产品,为开源界添砖加瓦呢?以笔者短浅的目光看来,我们对开源界贡献的东西恐怕很少,能够与国外经典开源项目一较高下的,少之又少矣!
作为一名中国的程序员,咱们能没有遗憾吗?为什么经典的 Web 不是中国人写的;为什么Linus 在大学时代就写出Linux并振臂一呼,应者云集;为什么JBoss能与巨无霸式的相抗衡;为什么MySQL能在和SQL 的夹击下发展并壮大…… ?如此等等问题 , 在遗憾之余,我想我们应该花点时间好好思考一下,中国的软件产业怎么了 , 中国的程序员又怎么啦?
在笔者看来,我们的程序员对开源的理解是相当狭隘的 。国学大师王国维曾说过,古往今来成大学问大事业者要经历三种境界,“昨夜西风凋碧树,独上高楼,望尽天涯路” , 这是第一重境界,迷惘也;“衣带渐宽终不悔 , 为伊消得人憔悴”,苦苦求索之境界也;第三重境界为“众里寻他千百度,蓦然回首,那人却在灯火阑珊处”,经历多少次的失败和挫折后,终于参透真谛,领悟真理 。我觉得开源也有三重境界:
首先,我们要敞开心胸 , 拥抱开源(Open to Open ) 。这重境界我们大家都能做到,拿来主义嘛 , 谁人不会 。当我们的项目需要数据库时,就去下载一个免费MySQL;需要IDE时,去下载 ;需要版本控制工具时,就去下载CVS;需要写搜索引擎时,可能是我们的最爱;当我们开发J2EE Web应用时,/JSF加/再加上或许成为我们的首选架构 。但是,我们绝大部分程序员都停留在这 个层次上,大家下载之后,看看文档介绍 , 安装、配置并能运行,就以为万事大吉,一切顺利 。偶尔遇到一些问题,去一搜,答案立马可得 。
其次,我们要深入开源,了解开源(Dig into Open ) 。要达到这个层次,就有些难度了 。我们不但要知其然,还要知其所以然 。“知其所以然”的最好办法就是下载源代码,仔细研读 , 揣摩并领会源代码的精义,看看这些经过诸多高手修改的源代码究竟藏有什么玄机 , 我们能从其中学习到哪些设计思想及设计模式,能复用其中哪些源代码 , 人家运用了哪些软件管 理思想把这些来自世界各地程序员的劳动汇集成一个产品,代码架构如何,软件配置管理又是怎样进行的……,等等等等,我们从源代码中学习的东西太多了 。在阅读源代码时 , 我们要多问自己几个为什么,这样就会收获更多 。
再次,我们要融入开源,贡献开源(Getin Open ) 。当我们彻底理解该项目源代码后,我们应发挥一下“人人为我,我为人人”的思想,或结合您的实际需要,或结合您的新想法 , 或针对Mail lists上的问题,对该开源项目加以改进和创新,并把自己的代码贡献出来,让大家评估 。当然,如果您有好的想法,您完全可以创建自己的开源项目,基金会中众多的开源项目不都是我们广大程序员一手创建的吗?但是,在创建新开源项目时 , 切忌不要重新发明轮子 。
笔者才疏学浅,想以 项目包中的核心项目为例,希望通过阅读源码,能从这个经典项目中学到更多的东西,为我们中国的开源事业起到抛砖引玉的作用 。
下面我们就开始我们的源码学习之旅 。
1. 下载.0的源代码
首先,我们得下载.0的源代码 。源代码的版本控制工具不是CVS,而是,如果您的机器上没有安装,请从下载并安装这个开源的版本控制工具 。当然,如果您想从中直接导入源代码,请从下载插件,即可导入源代码 。安装完成后,请在MS-DOS窗口中键入svnhelp,您将会看到:
C:/ and />svn help
: 产生一个无版本控制的目录树副本 。
用法: 1、 [-r REV] URL[@] [PATH]
2、 [-r REV] PATH1[@] [PATH2]
1、从 URL 指定的仓库 , 导出一个干净的目录树到 PATH 。如果有指定
REV 的话,内容即为该版本的 , 否则就是 HEAD 版本 。如果 PATH
被省略的话,URL的最后部份会被用来当成本地的目录名称 。
2、在工作副本中,从指定的 PATH1 导出一个干净的目录树到 PATH2 。如果
有指定 REV 的话,会从指定的版本导出,否则从工作副本导出 。如果
PATH2 被省略的话,PATH1 的最后部份会被用来当成本地的目录名称 。
如果没有指定 REV 的话,所有的本地修改都保留 , 但是未纳入版本控制
的文件不会被复制 。
如果指定了,将从指定的版本本开始查找 。
有效选项: 。。。。。。
我们看到给我们提供了非常友好的帮助,并且是中文的,看来中国程序员对这个开源项目有所贡献 。接下来,请在MS-DOS下键入:
svnD:///src/
这个命令的意思是把.0的源代码从库中导入到本机的D:///src/目录,命令运行后,您稍等几分钟,就会看到的源代码顺利导入到目标目录 。下面是源代码的目录机构,从这个目录结构中,我们可以看出该项目的开发者使用的IDE是,因为我们看到了熟悉的.及.文件 。如果您打算开发一个Stand alone的Java应用程序,不妨借鉴一下的目录结构 , 把脚本文件放在bin目录,将xml和配置文件放在conf目录中 , 把Java源码文件放在java或者src目录中,资源文件比如说图片文件,ini文件及其它的一些静态资源文件可以放在res目录,测试源代码可以放在test目录中 。这是一个典型的Java应用程序的目录机构,笔者以前曾接触到一个来自美国的产品,其源代码目录结构和及其相像 。
2. 编译并运行
代码下载后,我们接下来就是要编译并运行 。一提编译,我们不禁会想到可爱的Ant 。不错,正是以Ant作为编译工具,如果您还没有安装,请从 处下载并安装它 。然后,请从的源代码文件找到build..文件 , 并将该文件复制到build.,然后打开build.,找到下面这行:
base.path=/usr/share/java
【Tomcat6源码分析】将它改为:
base.path= D:///share
在编译过程中,Ant会让我们下载一些必要的依赖项目,base.path目录就是用来保存这些项目文件的 , 我们可以将这个属性指向一个已经存在的目录 。修改完base.path后,我们回到MS-DOS窗口,切换到源代码所在目录,然后运行ant 命令 , 如下图所示:
一分钟未到,Ant就告诉我们一个错误并提示我们编译失败,具体错误信息如下:
:
[get] :
[get] To: D:///share/file.zip
[get] Errorjava.io.n: :3080///drops/R-3.2-2/-JDT-3.2.zip
[get] Errorjava.io.n: :3080///drops/R-3.2-2/-JDT-3.2.zip
[get] Errorjava.io.n: :3080///drops/R-3.2-2/-JDT-3.2.zip
[get] Can't getto D:///share/file.zip
BUILD
D:///src/build.xml:554: Theerrorwhilethis line:
D:///src/build.xml:514: Can't getto D:///share/file.zip
Total time: 41
这个编译错误非常简单 , 就是找不到 文件 。有人可能会想,的编译和的JDT有什么关系?其实不然,是在下开发的,所以需要的JDT(Java)插件来编译Tomat源代码 。既然找不到,我们只好自己动手,上一搜,马上发现这个文件的有效下载地址为: 。我们打开刚才的build.文件,将其34行修改为:
jdt.loc=
修改保存build.文件后,重新开始ant 任务 。这次我们等的时间较长,因为-JDT-3.2.zip大约有19M,下载需要一段时间 。我们可乘此机会去泡杯茶弄点咖啡什么的 , 等我们品茶回来,发现敬业的蚂蚁Ant告诉我们编译成功,虽然编译器给出几个警告 。这时我们可发现刚才创建的base.path目录(D:///share)中已经下载了6个依赖项目,它们都是编译所必须的 。
下面就开始真正的编译任务了,请在MS-DOS窗口内键入ant并回车,Ant将在2分钟内编译1000多个源文件并将部署到目录 。编译顺利完成后 , 请打开的源代码目录,会发现多了一个目录,这是Ant的编译后的输出目录 。请打开源代码的/build/bin子目录,双击.bat文件 , 我们即可成功启动.0,此时我们的编译工作就算顺利完成了 。
3. 导入源代码到
3.1 请打开,新建一个Java项目,然后点击“Next”按钮,请选择“from”,并在文本框内填入我们刚才下载的源代码目录(i.e. D:///src) , 然后点击“Next”直至结束 。
文章插图
3.2 我们将会看到拒绝编译,这是因为找不到该项目指定的库文件 。请右击该项目,在弹出菜单中选择“”à“”,然后删除两个以开头的两个库文件,只保留一个JRE库文件,然后点击“OK”按钮,这时开始编译源代码,但是发现一堆错误,这是因为我们没有为该项目添加编译所必须的Jar包 。
3.3 准备好项目所必须的jar文件,其实,刚才我们运行ant 任务时,已经下载过这些jar文件包 。
ant.jar (请在ant安装目录的lib子目录中拷贝)
--3.1.jar (从刚才Ant下载的--3.1子目录中拷贝)
-dbcp-1.2.1.jar(从刚才Ant下载的-dbcp-1.2.1子目录中拷贝)
--1.1.jar(如果您本机没有这个jar包,请从处下载)
-pool-1.2.jar(从刚才Ant下载的-pool-1.2子目录中拷贝)
org..jdt..2.0.v_671.jar(从刚才Ant下载的/子目录中拷贝)
3.4 当我们准备好这些jar文件后,将这些文件拷贝到某一目录(比如说D:///目录),然后在中新建一个User,我们将这个新建的User 命名为,并把这些文件加到 。然后将我们新建的添加到项目 。另外,别忘了把JUnit库也加到项目 。这时开始重新编译,编译过程顺利通过,所有错误均消失,此时项目的目录结构如下:
还有 , 请把test目录也加入到源代码中,方法是在中右击”test”目录 , 然后在弹出菜单中选择“Build path”à”Use as”,之后我们会看到test目录上就多了个源代码的符号,如上图所示 。
3.5在中运行 。请找到的启动主类org....,右击这个类,在弹出菜单中选择“Run As…”à”Open Run …”,然后在弹出的“Run”窗口中填入程序运行参数“start”和JVM运行参数.home,如下面窗口所示:
然后点击“Run”按钮 , 我们将会看到正常启动 。恭喜,咱们的源码已经成功导入,这时,可视化的UML分析工具及Debug工具就能派上用场了 。
3.5 调试,请打开piler.类的源代码,在()方法的第一行打一个断点 , 然后在的调试状态下运行,等运行后 , 打开我们的浏览器 , 在地址栏中输入:8080//jsp/jsp2/el/basic-.jsp并回车,然后我们可观察到此时切换至调试视图:
文章插图
上面的小实验表明我们可以在中通过观察的内部运行机理 。另外补充一点,上面的方法是将jsp动态编译至java class,这个方法只是在第一次请求或者Jsp源码发生变化时执行,如果您再次在浏览器中发送同样的请求,您将看不到上图的Debug界面,因为该方法不再执行 。
另外,还有一点很有意思 。以前版本的源代码分散在好几个子项目中,他们分别叫做--5,--5,--,--和--,我觉得的开发者可能嫌这样做太麻烦了 , 所以版本中将这些子项目都合并在一起了 。但是,这种做法不利于我们阅读理解源代码 。
- 口袋妖怪漆黑的魅影裂空座物攻路线 口袋妖怪漆黑的魅影裂空座的详细分析攻略
- Spring Transaction 从实例读源码
- 母猪返情天数分析,母猪发情不明显是什么原因
- 5w1h是指什么 生产5w1h是指什么
- CyclicBarrier源码理解
- 尿常规检查结果分析表 尿常规检查结果分析
- 电梯调度需求分析 郭莉莉、李亚文
- 【软件工程】电梯调度程序需求分析李亚文郭莉莉
- 禽沙门氏菌病的真实案例分析 禽沙门氏菌的鉴别诊断
- 家畜有机磷农药中毒 家畜有机磷中毒的治疗案例及分析