`
JackyCheng2007
  • 浏览: 253946 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Tomcat源码学习 blog 收集 - Tomcat源码学习(一)

阅读更多
引自http://carllgc.blog.ccidnet.com/blog-htm-do-list-uid-4092-type-blog-dirid-13354.html

Tomcat源码学习(一)

作为一位Java程序员,如果您没有接触过开源软件、项目或框架的话,恐怕有些不可思议。轰轰烈烈的开源运动起源于Linux操作系统,Apache基金会在其中扮演了中流砥柱的角色,业界巨擘SUN,IBM, BEA 和Oracle等公司的积极参与,使得声势浩大的开源运动成为软件开发领域势不可挡的力量。2001年11月,IBM向Apache基金会捐献出Visual Age for Java,这个看似穷途末路的产品经众多高手的改造,演变为辉煌一时的Eclipse,直接击败了不开源的JBuilder,让做编译器起家的Borland公司几乎关张大吉。Eclipse这个产品如此经典,以至于微软的Visual Studio都得向它学习。在Apache Harmony的围追堵截下,Java的发明者Sun公司一看势头不妙,于2006年宣布Java开源,随后又公开了其旗舰级产品Solaris的源代码。今年1月,开源的死对头、冷酷自私的微软也不得不在MS-RL协议下公开.Net的源代码。但是,在这如火如荼的开源运动中,我们中国的程序员又有多少贡献呢,我们开创了哪些框架、项目和产品,为开源界添砖加瓦呢?以笔者短浅的目光看来,我们对开源界贡献的东西恐怕很少,能够与国外经典开源项目一较高下的,少之又少矣!

作为一名中国的程序员,咱们能没有遗憾吗?为什么经典的Apache Web Server不是中国人写的;为什么Linus Torvalds在大学时代就写出Linux并振臂一呼,应者云集;为什么JBoss能与巨无霸式的Websphere相抗衡;为什么MySQL能在Oracle和SQL Server的夹击下发展并壮大…… ?如此等等问题,在遗憾之余,我想我们应该花点时间好好思考一下,中国的软件产业怎么了,中国的程序员又怎么啦?

在笔者看来,我们的程序员对开源的理解是相当狭隘的。国学大师王国维曾说过,古往今来成大学问大事业者要经历三种境界,“昨夜西风凋碧树,独上高楼,望尽天涯路”,这是第一重境界,迷惘也;“衣带渐宽终不悔,为伊消得人憔悴”,苦苦求索之境界也;第三重境界为“众里寻他千百度,蓦然回首,那人却在灯火阑珊处”,经历多少次的失败和挫折后,终于参透真谛,领悟真理。我觉得开源也有三重境界:

首先,我们要敞开心胸,拥抱开源(Open to Open Source)。这重境界我们大家都能做到,拿来主义嘛,谁人不会。当我们的项目需要数据库时,就去下载一个免费MySQL;需要IDE时,去下载 Eclipse;需要版本控制工具时,就去下载CVS;需要写搜索引擎时,Lucene可能是我们的最爱;当我们开发J2EE Web应用时,Struts/JSF加Hibernate/iBATIS再加上Spring或许成为我们的首选架构。但是,我们绝大部分程序员都停留在这个层次上,大家下载之后,看看文档介绍,安装、配置并能运行,就以为万事大吉,一切顺利。偶尔遇到一些问题,去Google一搜,答案立马可得。

其次,我们要深入开源,了解开源(Dig into Open Source)。要达到这个层次,就有些难度了。我们不但要知其然,还要知其所以然。“知其所以然”的最好办法就是下载源代码,仔细研读,揣摩并领会源代码的精义,看看这些经过诸多高手修改的源代码究竟藏有什么玄机,我们能从其中学习到哪些设计思想及设计模式,能复用其中哪些源代码,人家运用了哪些软件管理思想把这些来自世界各地程序员的劳动汇集成一个产品,代码架构如何,软件配置管理又是怎样进行的……,等等等等,我们从源代码中学习的东西太多了。在阅读源代码时,我们要多问自己几个为什么,这样就会收获更多。

再次,我们要融入开源,贡献开源(Get involved in Open Source)。当我们彻底理解该项目源代码后,我们应发挥一下“人人为我,我为人人”的思想,或结合您的实际需要,或结合您的新想法,或针对Mail lists上的问题,对该开源项目加以改进和创新,并把自己的代码贡献出来,让大家评估。当然,如果您有好的想法,您完全可以创建自己的开源项目, Apache基金会中众多的开源项目不都是我们广大程序员一手创建的吗?但是,在创建新开源项目时,切忌不要重新发明轮子。

笔者才疏学浅,想以Apache Jakarta项目包中的核心项目Tomcat为例,希望通过阅读源码,能从这个经典项目中学到更多的东西,为我们中国的开源事业起到抛砖引玉的作用。

下面我们就开始我们的Tomcat源码学习之旅。

1. 下载Tomcat6.0的源代码

首先,我们得下载Tomcat6.0的源代码。Tomcat源代码的版本控制工具不是CVS,而是Subversion,如果您的机器上没有安装Subversion,请从 http://subversion.tigris.org/servlets/ProjectDocumentList?folderID=91 下载并安装这个开源的版本控制工具。当然,如果您想从Eclipse中直接导入Tomcat源代码,请从http://subclipse.tigris.org/update_1.0.x下载Subversion插件,即可导入Tomcat源代码。安装完成后,请在MS-DOS窗口中键入svn export help,您将会看到:

C:\Documents and Settings\carlwu>svn help export

export: 产生一个无版本控制的目录树副本。

用法: 1、export [-r REV] URL[@PEGREV] [PATH]

2、export [-r REV] PATH1[@PEGREV] [PATH2]

1、从 URL 指定的仓库,导出一个干净的目录树到 PATH。如果有指定

REV 的话,内容即为该版本的,否则就是 HEAD 版本。如果 PATH

被省略的话,URL的最后部份会被用来当成本地的目录名称。

2、在工作副本中,从指定的 PATH1 导出一个干净的目录树到 PATH2。如果

有指定 REV 的话,会从指定的版本导出,否则从工作副本导出。如果

PATH2 被省略的话,PATH1 的最后部份会被用来当成本地的目录名称。

如果没有指定 REV 的话,所有的本地修改都保留,但是未纳入版本控制

的文件不会被复制。



如果指定了 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:\carl_wu\tomcat\src\目录,命令运行后,您稍等几分钟,就会看到Tomcat的源代码顺利导入到目标目录。下面是源代码的目录机构,从这个目录结构中,我们可以看出该项目的开发者使用的IDE是Eclipse,因为我们看到了熟悉的.project及.classpath文件。如果您打算开发一个Stand alone的Java应用程序,不妨借鉴一下Tomcat的目录结构,把脚本文件放在bin目录,将xml和properties配置文件放在conf目录中,把Java源码文件放在java或者src目录中,资源文件比如说图片文件,ini文件及其它的一些静态资源文件可以放在res目录,测试源代码可以放在test目录中。这是一个典型的Java应用程序的目录机构,笔者以前曾接触到一个来自美国的产品,其源代码目录结构和Tomcat及其相像。






2. 编译并运行

代码下载后,我们接下来就是要编译并运行Tomcat。一提编译,我们不禁会想到可爱的Ant。不错,Tomcat正是以Ant作为编译工具,如果您还没有安装,请从http://ant.apache.org/bindownload.cgi 处下载并安装它。然后,请从Tomcat的源代码文件找到build.properties.default文件,并将该文件复制到build.properties,然后打开build.properties,找到下面这行:

base.path=/usr/share/java

将它改为:

base.path= D:/carl_wu/tomcat/share

在Tomcat编译过程中,Ant会让我们下载一些必要的依赖项目,base.path目录就是用来保存这些项目文件的,我们可以将这个属性指向一个已经存在的目录。修改完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有什么关系?其实不然,Tomcat是在Eclipse下开发的,所以需要Eclipse的JDT(Java Development tooling)插件来编译Tomat源代码。既然找不到,我们只好自己动手,上Google一搜,马上发现这个文件的有效下载地址为: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任务。这次我们等的时间较长,因为eclipse-JDT-3.2.zip大约有19M,下载需要一段时间。我们可乘此机会去泡杯茶弄点咖啡什么的,等我们品茶回来,发现敬业的蚂蚁Ant告诉我们编译成功,虽然编译器给出几个警告。这时我们可发现刚才创建的base.path目录(D:\carl_wu\tomcat\share)中已经下载了6个依赖项目,它们都是Tomcat编译所必须的。

下面就开始真正的编译任务了,请在MS-DOS窗口内键入ant并回车,Ant将在2分钟内编译1000多个源文件并将Tomcat部署到output目录。编译顺利完成后,请打开Tomcat的源代码目录,会发现多了一个output目录,这是Ant的编译后的输出目录。请打开Tomcat源代码的output\build\bin子目录,双击startup.bat文件,我们即可成功启动Tomcat6.0,此时我们的编译工作就算顺利完成了。


3. 导入源代码到Eclipse

3.1 请打开Eclipse,新建一个Java项目,然后点击“Next”按钮,请选择“Create project from existing source”, 并在Directory文本框内填入我们刚才下载的Tomcat源代码目录(i.e. D:\carl_wu\tomcat\src),然后点击“Next”直至结束。




3.2 我们将会看到Eclipse拒绝编译,这是因为Eclipse找不到该项目指定的库文件。请右击该项目,在弹出菜单中选择“Properties”à“Libraries”,然后删除两个以TOMCAT_LIBS开头的两个库文件,只保留一个JRE库文件,然后点击“OK”按钮,这时Eclipse开始编译Tomcat源代码,但是发现一堆错误,这是因为我们没有为该项目添加编译所必须的Jar包。

3.3 准备好Tomcat项目所必须的jar文件,其实,刚才我们运行ant download任务时,已经下载过这些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项目的目录结构如下:





还有,请把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”窗口中填入程序运行参数“start”和JVM运行参数catalina.home,如下面窗口所示:




然后点击“Run”按钮,我们将会看到Tomcat正常启动。恭喜,咱们的Tomcat源码已经成功导入Eclipse,这时,可视化的UML分析工具及Debug工具就能派上用场了。

3.5 调试Tomcat,请打开org.apache.jasper.compiler.Compiler类的源代码,在generateJava()方法的第一行打一个断点,然后在Eclipse的调试状态下运行Tomcat,等Tomcat运行后,打开我们的浏览器,在地址栏中输入http://localhost:8080/examples/jsp/jsp2/el/basic-comparisons.jsp并回车,然后我们可观察到Eclipse此时切换至调试视图:







上面的小实验表明我们可以在Eclipse中通过Debugger观察Tomcat的内部运行机理。另外补充一点,上面的generateJava方法是将jsp动态编译至java class,这个方法只是在第一次请求或者Jsp源码发生变化时执行,如果您再次在浏览器中发送同样的请求,您将看不到上图的Debug界面,因为该方法不再执行。

另外,还有一点很有意思。Tomcat6以前版本的源代码分散在好几个子项目中,他们分别叫做jakarta-servletapi-5,jakarta-tomcat-5,jakarta-tomcat-catalina,jakarta-tomcat-connectors和jakarta-tomcat-jasper,我觉得Tomcat的开发者可能嫌这样做太麻烦了,所以Tomcat6版本中将这些子项目都合并在一起了。但是,这种做法不利于我们阅读理解源代码。
分享到:
评论
4 楼 a_alter 2011-12-06  
虽然晚了点啊 特意登陆上来 留个言。 这就是前人载树啊  Tomcat 的源码还是很有分量的 多谢
3 楼 runningsnail 2010-07-20  
好好研读一番,写的很有意境。
2 楼 JackyCheng2007 2008-04-30  
不好意思,这篇文章也是我引别人的,我的学习尚在起步。也很高兴能和你交流。

http://carllgc.blog.ccidnet.com/blog-htm-do-list-uid-4092-type-blog-dirid-13354.html

这里面很有几篇好文章。
1 楼 rmn190 2008-04-30  
太好了,真佩服博主的文采与精神.

这段时间我也在研究Tomcat的源码,惊喜之外有很多问题把自己搞的很郁闷,今天看到博主的Tomcat源码学习系列真是喜不自禁.

我MSN是:rmn190@hotmail.com,能否在MSN里向博主请教?

相关推荐

    tomcat-connectors-1.2.48-src

    《深入理解Tomcat连接器:剖析tomcat-connectors-1.2.48-src源码》 Tomcat作为一款广泛使用的开源Java应用服务器,其在处理Web应用方面扮演着核心角色。而Tomcat的连接器(Connector)是其与外部世界交互的关键组件...

    Tomcat源码apache-tomcat-8.5.47-src.zip

    在开始学习Tomcat源码之前,首先需要了解一些基本概念。Java Servlet是Java平台上的一个标准接口,用于处理HTTP请求。而JSP则是用于创建动态网页的Java技术,它将业务逻辑和页面展示分离。Tomcat作为Servlet容器,...

    apache-tomcat-6.0.35和apache-tomcat-6.0.35 src

    Apache Tomcat是一款开源的Java Servlet容器,主要用于实现JavaServer Pages (JSP)、Servlet和Java EE的Web应用程序。在这个压缩包中,包含了两个版本:`apache-tomcat-6.0.35` 和 `apache-tomcat-6.0.35 src`。前者...

    jakarta-tomcat-connectors-1.2.15-src.tar.gz

    《Jakarta Tomcat Connectors ...通过研究这个源码包,开发者不仅可以学习到Apache Tomcat Connectors的设计理念和实现,还能增强自身的系统编程和网络编程能力,对于提升在Java Web开发领域的专业素养具有重要意义。

    tomcat-redis-session-manager-master

    "tomcat-redis-session-manager-master" 是一个项目名称,表明这是一个与Tomcat(一个流行的Java应用服务器)和Redis(一个开源的内存数据结构存储系统)相关的session管理器的主分支。通常,这样的项目是用来实现将...

    jakarta-tomcat-connectors-jk-1.2.6-src.tar.gz

    标题中的"jakarta-tomcat-connectors-jk-1.2.6-src.tar.gz"是一个源码压缩包,其中包含了Jakarta Tomcat Connectors(JK)的版本1.2.6的源代码。Jakarta Tomcat Connectors是Apache Tomcat服务器的一部分,用于处理...

    apache-tomcat-9.0.34-src.zip

    通过分析和学习Tomcat的源代码,你可以了解到以下知识点: 1. **Servlet和JSP处理**:Tomcat如何解析和处理HTTP请求,以及如何调用Servlet和JSP进行响应生成。 2. **线程模型**:了解Tomcat如何使用线程池来处理...

    tomcat-connectors-1.2.44-src.tar

    这个名为"tomcat-connectors-1.2.44-src.tar"的压缩包包含了Tomcat Connectors的1.2.44版本源代码,对于开发者来说,它是一份宝贵的资源,可以让我们深入学习和理解Tomcat的工作机制。"亲测可用,安装方便"的描述,...

    tomcat-redis-session-manager-master.zip

    通过对源码的学习和实践,开发者可以更好地理解和掌握这一技术,提升系统的可扩展性和稳定性。在实际应用中,我们还需要结合具体业务需求,灵活调整配置和优化策略,以实现最优的session管理效果。

    tomcat-connectors-1.2.40-src.zip

    五、源码学习价值 1. 性能优化:通过阅读源码,我们可以了解请求处理流程中的瓶颈,优化线程池、缓冲区大小等参数,提升系统性能。 2. 扩展功能:根据需求,可以对现有协议进行扩展,如支持新的网络协议,或实现更...

    Tomcat源码学习:一个最简单的“Tomcat”

    【标题】"Tomcat源码学习:一个最简单的‘Tomcat’",这篇博客主要探讨的是如何通过学习Tomcat的源代码来理解这个流行的开源Java Servlet容器的工作原理。Tomcat是Apache软件基金会的一个项目,它是Java Web应用...

    tomcat源码学习之环境搭建

    在深入探讨Tomcat源码学习之前,我们首先要...总之,Tomcat源码学习是一个深入理解Java Web服务原理和最佳实践的过程。通过这个过程,你不仅可以提升自己的编程技能,还能更好地解决实际问题,提升服务器性能和稳定性。

    apache-tomcat-9.0.54-src.zip

    - 调试Tomcat源码可以定位并解决运行时问题,例如性能瓶颈、内存泄漏或安全漏洞。 6. **扩展与定制** - Tomcat允许开发者自定义其行为,例如通过编写监听器、过滤器或servlet来扩展其功能。 - 可以通过编写自己...

    jakarta-tomcat-connectors-1.2.15-src.zip

    【标题】"jakarta-tomcat-connectors-1.2.15-src.zip" 是一个包含Apache Tomcat连接器源代码的压缩包,主要用于帮助开发者深入理解Tomcat的工作原理,并进行自定义或扩展。 【描述】提到的"jakarta_tomcat_...

    tomcat-connectors-1.2.42-src.tar.gz

    【标题】"tomcat-connectors-1.2.42-src.tar.gz" 是Apache Tomcat服务器的一个源码包,主要用于实现Tomcat与Web服务器(如Apache HTTP Server)之间的连接器功能。这个版本号1.2.42表示这是Tomcat Connectors的一个...

    tomcat-connectors-1.2.27-src.tar.gz

    《深入解析Tomcat Connectors:基于1.2.27源码分析》 Tomcat Connectors,也称为Coyote,是Apache Tomcat服务器的核心组件之一,它负责处理网络连接和HTTP协议。在深入理解Tomcat Connectors之前,我们需要先了解...

    apache-tomcat-8.5.68-src

    通过深入学习Apache Tomcat 8.5.68的源代码,开发者不仅可以理解Web服务器的工作原理,还可以掌握如何定制Tomcat以满足特定需求,进一步提升应用程序的性能和稳定性。同时,这也是Java Web开发人员进阶的重要一步。

    tomcat-7.0.90-src-源码

    深入Tomcat源码,我们可以学习到以下关键知识点: 1. **Web应用部署**:Tomcat如何解析`WEB-INF/web.xml`配置文件,加载Servlet和Filter,以及如何根据`META-INF/context.xml`设置上下文参数。 2. **生命周期管理*...

    tomcat-redis-session-manager 支持 tomcat7 ,包含源码和jar

    本文将围绕"tomcat-redis-session-manager"这一插件,详细探讨它如何支持Tomcat7,以及其源码和使用方法。 首先,"tomcat-redis-session-manager"是专为Tomcat设计的一个session管理器,用于将Tomcat的session数据...

    tomcat-servlet-api-9.0.0.M17-sources.jar

    tomcat-servlet-api-9.0.0.M17 源码jar包,包里是源码文件,可以直接做jar包使用也可以学习里面的源码调试。

Global site tag (gtag.js) - Google Analytics