The Tomcat Servlet/JSP Container

Apache Tomcat 5.5 Servlet/JSP 容器

Jaxmao Logo

Links

Contents

应用开发人员指南

源代码组织(Source Organization)

Printer Friendly Version
print-friendly
version
Directory Structure

在下面的描述中使用变量名$CATALINA_HOME来代指Tomcat5所安装的目录地址,这是一个基础目录(base directory),其他的相关路径由它而派生。不过,如果你已经把Tomcat设置成多个体实例(multiple instances),并且设立了一个$CATALINA_BASE目录,那么你就应使用$CATALINA_BASE而不是$CATALINA_HOME作为参照。

这个手册特别建议你把包含源代码的目录阶层(本章节所描述的)和包含可调度程序的目录阶层(前面章节所描述的)分开。保持这种分离有下面几种好处:

  • 如果没有和“可运行”版的程序相混合,源代码目录里的内容就比较容易来管理,移动和备份(backup)。

  • 在只含有源代码文件的目录里,管理控制源代码就比较容易。

  • 当可调度阶层目录被分开后,就比较容易来选择那些组成可安装分配(installable distribution)程序的文件。

我们将会看到,ant开发工具使得产生和处理这样的目录阶层非常容易。

你可以随意组织用来包含程序源代码的目录和文件阶层。不过,下面的这种组织结构被证明非常实用可行,也是下面将要讨论的例子build.xml配置文件(configuration file)所期望的。所有的这些组成成分存在于你的应用程序的最上层项目源代码目录下面。

  • docs/ —— 关于你的应用程序的文档资料,可以用你们开发组使用的任何格式(format)。

  • src/ —— Java源代码文件,它们是用于产生你的程序特有的servlets, beans, 和其他Java classes。如果你的源代码被组织成包(packages)(我们极力推荐),这个包阶层(hierarchy)就应该被放置这个目录下面。

  • web/ —— 组成你网站的静态文件(HTML页面,JSP页面,JavaScript文件,CSS stylesheet文件,和图象),这些文件都可以让客户存取(accessible)。这个目录是你的网络程序的文件根(document root)目录,它的任何子目录中的文件可通过浏览器来读取。

  • web/WEB-INF/ —— 你的程序所需的特别的配置文件,包括网络应用程序调度符(web.xml,在Servlet规范里有定义),你为用户标记库(custom tag libraries)所产生的标记库描述符,以及其他你想要包括在网络程序里的资源文件(resource files)。尽管这个目录显得象是文件根目录(document root)的分目录(subdirectory),但是Servlet规范不允许客户能直接使用这个目录里的内容(或它包含的任何文件)。所以,这是一个不错的地方来储存那些程序顺利运行所必须的,但又是非常敏感的配置信息(比如数据库连接用的用户名称及密码)。

在程序开发过程中,会临时产生另外两个目录:

  • build/ —— 执行默认ant指令后,会在这个目录中产生与web应用档案(WAR)完全相同的文件。Tomcat5允许你在象这样未包装的目录里调度程序,你可以把此目录复制到$CATALINA_HOME/webapps 目录上去,或通过“管理者”(Manager)程序把它安装上去。后面的这种处理方式在开发程序中非常有用,下面我们会作些说明。

  • dist/ —— 当你执行ant dist目标后,就会在这个目录中产生与你的网络程序binary distribution 完全相同的文件,包括许可证信息,文档资料和README 文件。

注意 — 要把这两个目录存档在你的源代码控制系统里,因为这两个目录会在程序开发中根据需要被删除或重新产生。正是因为这个原因,如果你想要保留一个关于程序更改的固定记录,你就要在这两个目录里编辑源代码文件,因为下一次执行build命令时,所有的程序更改就会被遗失掉。

External Dependencies

如果你的程序需要外部的项目或包(packages)里的JAR文件(或其他资源),那你应该怎么办呢?一个通常的例子就是你必需在你的程序中引入JDBC驱动程式才能运作。

不同的开发人员采用不同的方式来处理这个问题。有些开发人员会鼓励你对于每一个需要那些JAR文件的程序,把它所依赖的JAR文件复制到源代码控制存档(archives)上。不过,当你在许多程序中使用同样一个JAR文件——特别是当你面临着需要升级(upgrade)到不同版本的JAR文件时,就会产生很严重的管理上的问题。

因此,这个手册提倡要把你所需要的packages的复制件存放在程序的源代码控制档案里。相反,你应该把这些外部依赖性文件整合到创建你的程序的过程中去。这样一来,你总是可以从系统管理员安装JAR文件的地方选择合适版本的JAR文件,而用担心每次在你所依赖的JAR文件更改后,要去更新你的程序。

在例子Ant build.xml 文件中,我们将示范怎样去定义那些让你能够配置复制文件地址的build properties,而不需要在这些文件更改时去修改 build.xml 。每个开发人员使用的build属性(properties)可以根据每个不同的程序客户化,或者默认作(defaulted to)“标准”build属性存放在开发人员的主目录(home directory)中。

在许多情况下,系统管理员可能已经把必需的JAR文件安装到Tomcat 5 的 common/lib 或者shared/lib 目录里。如果这已经被做好了,你就不需要再做什么——例子build.xml 会自动创造一个包含这些文件的compile classpath 。

Source Code Control

如先前提到的,我们极力建议你把组成你程序的所有源代码文件放置在一个象Concurrent Version System (CVS)一样的源代码控制系统下来管理。如果你选择这么做,在这个源代码阶层里的每一个目录和文件都会被注册和保存——但是所有产生的文件都不会被注册和保存。如果你注册二进制形式的文件(如图象或JAR库),一定要指示你的源代码控制系统。

我们(在前面一段)建议你不要把你在开发程序过程中产生的build/dist/ 目录中的内容存放在源代码控制系统里。一个简单的办法让CVS忽略这两个目录就是在你的上层源代码目录中产生一个叫做.cvsignore(注意前面有一个句点)的文件,它应该包括下面这些内容:

build 
dist 
build.properties

对于在这里提及build.properties的理由,我们会在开发过程这一章节里作解释。

关于源代码控制环境的详细说明超过了本手册的范围。不过,如果你使用命令行的CVS客户端,你要遵守下面的步骤:

  • 要更新储存在源代码储存器(source repository)里的源代码,得到你的源代码目录中去执行cvs update -dP

  • 当你要在源代码目录阶层产生一个新的子目录(subdirectory),得到CVS使用象cvs add {子目录名称(subdirname)}的命令来注册。

  • 当你首次产生一个新的源代码文件,找到包括源代码的目录,并用诸如象cvs add {filename}这样的命令来注册这个新文件。

  • 如果你不再需要某个特定的源代码文件,找到包括这个文件的目录,并且删除它。然后在CVS使用象cvs remove {filename}这样的命令来注销这个文件。

  • 在你产生,修改和删除源代码文件时,这些改变还没有反映在服务器端的储存器里。要保持目前的更改,得到项目的源代码目录去执行cvs commit 。你会被要求简述你刚才完成的更改,然后和新版本的源代码文件一起被储存下来。

CVS,象其他源代码控制系统一样,有许多额外的特性(比如能够对特定发行版的文件进行标记,支持开发多个分枝版本—这些分枝在以后可以被合并)。更多信息请参看简介中的链连(link)和参考资料(reference)。

BUILD.XML Configuration File

我们将利用ant工具来管理编译Java源代码文件,以及产生调度目录层次。Ant在一个构建(build)文件控制下操作,通常叫做build.xml,它定义了必需的开发过程的步骤。这个文件储存在你的源代码目录层次的最上层,必须把它读入(check in)到你的源代码控制系统中去。

就象一个Makefile,build.xml文件提供了几个“目标”("target")来支持可选择性的开发活动(比如产生相关的Javadoc文件,擦除调度主目录以便你能从头开始你的项目,或者产生网络应用档案文件以便你可以分配你的程序)。一个构造不错的build.xml文件应该包括描述说明那些设计给开发人员使用的目标(target)的内部文件,以及这些内部使用的目标。要求Ant显示项目的说明资料,你要更换到含有build.xml的目录下,然后打印命令:

ant -projecthelp

为了让你能先做起来,我们提供了basic build.xml 文件,你可以对它用户化并把它安装在你的项目源代码目录中。这个文件包括了描述各种可被执行目标的注释。简单地说,它通常提供了下面的这些目标:

  • 清除(clean)——这个目标删除既存的builddist 目录,这样它们可以被重新构造。这样确保你不可能发生因为修改源代码,但没有重新编译(recompiling)所有affected classes,而在运行时出现问题。

  • 编译(compile)——这个目标是用来编译那些自从上次编译后被更改过的源代码。所产生的类文件(class files)被放置在build目录下的子目录WEB-INF/classes 里面,和网络应用程序的结构所要求完全一致的地方。因为这个命令在开发程序过程中经常被执行,所以通常把它设置为“默认(default)”目标,这样一来简单的ant命令就可以执行它。

  • all ——这个目标是一个用来先执行清除目标,然后再执行编译目标的捷径(short cut)。因此,它确保你重新编译所有的程序,这样可以保证你不会在不知不觉中引入一些不相适宜的改变。

  • javadoc ——这个目标产生网络程序中Java类的Javadoc API文档资料。例子build.xml 文件中假设你想把API文档资料包括在你要发表的程序中,所以它把产生的文档资料(docs)放在dist目录下的子目录里。因为你通常不需要在每次编译时都产生Javadocs API文档资料,所以这个目标和dist目标相关联,而与compile目标无关。

  • dist ——这个目标给你的程序产生一个分配目录,包括必要的文档资料,Java类的Javadocs,网络应用档案(WAR)文件,这个WAR文件将被传送给需要安装你的程序的系统管理员。因为这个目标也依赖于deploy目标,网络应用档案还应包括必需的外部文件。

为了用Tomcat5进行互动开发和测试你的程序,我们定义了下面额外的几个目标(targets):

  • 安装(install)——告诉正在运行的Tomcat5使你开发的程序可被立即用于执行和测试。它不需要重新启动Tomcat5。

  • 重新装载(reload)—— 一但程序安装后,你可以继续更改和用compile目标重新编译。Tomcat5 会自动识别JSP页面里的更改,但不能识别servlet 或 JavaBean 类里的更改——这个命令会告诉Tomcat重新启动最近安装的程序,这样这些改变就会被认可。

  • 删除(remove)——当你完成了开发和测试活动,你可以选择性地告诉Tomcat5把这些程序去掉。

利用开发和测试目标还需要额外的一些一次性设置,这一点我们在下一页会讨论。


Copyright © 1999-2006, Apache Software Foundation