Programmer’s Blog

Monday, July 24, 2006

 

剖析 Shale 应用程序

你好,Shale: 剖析 Shale 应用程序
Shale 由内向外的目录结构
文档选项
将此页作为电子邮件发送

将此页作为电子邮件发送

未显示需要 JavaScript 的文档选项


最新推荐

级别: 初级

Brett McLaughlin (brett@newInstance.com), 作家和编辑, O'Reilly Media, Inc.

2006 年 6 月 05 日

通过对框架的应用目录结构的详细分析,Brett McLaughlin 继续深入介绍 Shale。利用 本系列第一篇文章 中介绍的 Shale starter 应用程序,Brett 详细地为您介绍从 src/ 到 dist/ 的核心目录。本文介绍了 Shale 库的存储方式,定制文件的放置位置以及在何处向 Shale 应用程序插入专门的行为。在本文中,他给您提出一些关于管理 Shale 目录的重要建议,并且让您从一个示例应用程序(基于 Shale starter 应用程序)开始学起,该示例应用程序将作为本系列其余文章讨论的基础。

这个分为五部分的系列的第一篇文章 中,我介绍了 Shale 并解释了它与它的前一代 Struts 的不同之处。文中介绍了 Shale 的理论基础并为您演示了如何安装和设置开发环境。 还讨论了 Shale 可能存在的一些弱点 —— 也就是它是一个正在发展中的产品 —— 但我们也得出了结论,对于那些愿意随其不断改进和学习的开发人员来说,Shale 是一个很有前途的新开发框架。

在本文中,我把改进与学习这一项放到测试中,同时对 Shale 应用程序进行彻底深入的分析。本文首先重新探讨 Shale 所谓的 starter 应用程序(您将很快发现,这实际上是一个模板),以便您能确切地了解它为 Web 应用程序开发带来的好处。使用 starter 应用程序构建您自己的示例应用程序,然后使用它们浏览许多构成最基本的 Shale 应用程序的文件和目录。在本文中,我将为您说明把 JSP 和 Java™ 类放在何处并解释 Shale 是如何简化构建功能全面的、定制的 Web 应用程序的过程。

本文中的大多数讨论以本系列第一篇文章介绍的知识为基础。如果您还未曾阅读那篇文章,您应该 立即阅读

开始使用 Shale

正如您在上一篇文章中学到的,开始构建 Shale 应用程序的最容易的方法就是以 Shale starter 应用程序作为模板,然后在此基础上进行修改。因为本文非常需要您进行实际操作,因此现在您首先要做的是启动该 starter 应用程序。学习 starter 程序中的各种组件(通过应用程序的目录结构)及其协同工作的方式对稍后谈到的创建自己的 Shale 应用程序很有帮助。

嗨,那是一个模板!

实际上如果沿用 Hello World 的说法,与其说 Shale starter 应用程序是 “starter 应用程序” 不如说是一个模板。该模板确实能帮助您开始使用 Shale 开发应用程序。它提供了能轻松扩展您自己的 Shale 应用程序的基本设置,还考虑到了您可能需要的所有常规依赖 JAR 文件。 考虑与 Shale 一起提供的 starter 应用程序时,应把它视为一个可作为开发基础的模板,而不是一旦能够轻松使用 Shale 后就不再使用的示例应用程序。

实际上,使用 starter 应用程序开始 Shale 应用程序开发项目 是一个好主意。我在上一篇文章中说明了设置 Shale starter 应用程序的过程,本文假定您已完成了那些基础工作。您应该已经把 Shale starter 应用程序复制到开发环境中称为 “first-shale” 的目录中。first-shale 目录中的代码是您个人的 starter 应用程序,您将使用它们了解所有的 Shale 应用程序结构。

核心目录结构

假定您已经从 Shale starter 应用程序复制了自己的应用程序(first-shale),查看一下应用程序的目录结构。您将看到许多文件。如果不能确定每个组件、文件和目录的具体用 途,应用程序能够显示出一些它们的主要用处 —— 至少在开始时。图 1 显示的是目录结构;如您所见,starter 应用程序中有许多文件:


图 1. Shale starter 应用程序目录结构
Shale starter 应用程序目录结构

首先从展开 Shale starter 应用程序目录结构开始。

与构建有关的文件

starter 应用程序根目录下的前两个文件是 build.xml 和 default.properties。如果您使用过 Ant 构建环境,应该对第一个文件比较熟悉。总体来说,build.xml 告知 Ant 做什么。就 Shale starter 应用程序而言,它使 Ant 了解编译哪些文件以及如何创建 WAR 分发和 servlet 引擎(本文稍后深入讨论)所用的文件。

default.properties 文件是用来指定几个 Shale 的依赖项的模板。是的,这就意味着在模板应用程序(Shale starter 应用程序)中有一个模板文件(default.properties)。由于本系列( 参见 参考资料) 第一篇文章已介绍了 default.properties,故这里不再讨论相关细节。大体上,把该文件复制为名为 build.properties 的新文件,对特定于环境的部分进行更改,然后使用 Ant 构建项目。在 Ant 运行时,它使用 build.properties 中指定的位置来创建 Shale 分发。

依赖目录

接下来看见上面有两个空目录: ext/ and lib/。特意将其留空,不要以为您丢失了什么。构建 Shale Web 应用程序、设置 build.properties 文件时,您必须指出 Shale 框架和 servlet 引擎应该到哪里查找依赖项。实际上,可以指定两种类型 的依赖项:

  • 应用程序在编译时和运行时需要的 JAR 文件。这些文件应该是应用程序 WAR 文件的一部分并位于 Web 应用程序的 WEB-INF/lib/ 目录中。

  • 应用程序在编译时而不是 运行时所需的 JAR 文件。这种情况通常是在运行时 servlet 容器提供一组库,但在编译应用程序时需要用到它们。不应该在 Web 应用程序的 WAR 文件中包含这种文件,因为容器将运行时提供该类文件。

build.properties 文件提供一个指定运行时依赖项(使用 lib.dir 属性)和不应该存在于运行时 WAR 部署配置(使用 ext.dir 属性)中的编译时依赖项的途径。如果愿意,您可以仅把依赖项放置在如下目录中:

  • 运行时依赖项放在 lib/ 目录下
  • 仅编译时依赖项放在 ext/ 目录下

这两个空目录是专门为此而提供的。

文档

LICENSE.TXT、NOTICE.txt 和 README.txt 是简单的文档文件。这些文档详述了能够使用 Shale 的条件和能够对框架做哪些修改。它们也对设置和构建 Shale 应用程序提供简单的指导。这些文件值得阅读一遍,但是读过一遍以后,您可以忽略它们。

源代码

最后一个名为 src/ 的目录应该比较容易理解:它包含 Shale starter 应用程序的源代码。该目录包含的文件并不多,但有许多子目录。因此,它的结构看起来比实际复杂。图 2 显示了完整的、展开的源代码目录结构:


图 2. 源代码目录结构
Shale starter 应用程序的源代码目录有许多子目录

下面仔细分析一下这些子目录:

  • conf/ 包含一个文件 —— MANIFEST.MF,为应用程序生成 WAR 文件时,构建进程将定制和使用该文件。在典型的应用程序开发周期中,您不需要使用和修改该文件。

  • java/ 实际上只包含在 starter 应用程序中使用的类。org.apache.shale.blank.WelcomeBean 是一个演示如何将 Shale 与 Beans 一起使用的简单 JavaBean。更为重要的是,它指示能把 Java 文件放置在 starter 应用程序中的何处。构建 starter 应用程序时,ANT 将自动编译 java/ 目录下的所有 Java 代码。因此,如果您添加自己的代码,可以把代码放在 java/ 目录(目录结构等等)下,Ant 编译这些代码并把它们包含在应用程序的构建中。

  • test/ 和 systest/ 只包含能确保 starter 应用程序构建和运行正确的测试。除非您要处理 Shale 框架或 starter 应用程序本身,否则它们与您没有太大关系。

  • web/ 包含在 starter 应用程序中使用的 JSP。可以把您想在应用程序中包含的任何 JSP 添加到该子目录,它们将被添加到构建中。

很明显,大多数令人感兴趣的 Shale starter 的组件位于 src/ 目录下。开发愈加复杂的 Shale 应用程序时,您的 src/ 目录将装满您自己的 Java 类和 JSP。因此要习惯于在 Shale starter 应用程序的 src/ 目录结构下工作;您将发现这在应用程序开发中会非常有用。





回页首


创建应用程序

一旦很清楚 starter 应用程序的最初目录结构,您将深入分析构建 Shale 应用程序时它是什么样子。 在上一节,您看到了 Shale 应用程序的源代码位于何处。在本节中,将学习如何把源代码构建到 Web 应用程序中以及把所有已编译的 Java 文件、JSP 页面和相关的依赖项放置在何处。

在创建过程中,您将很好地理解如何部署 Shale 应用程序以及可以在何处修改标准部署选项。您也会知晓在何处添加用于附加插件或想要和 Shale 代码一起使用的依赖项的库。

构建 starter 应用程序

回顾一下上一篇文章中介绍的 starter 应用程序的构建方式,下面让我们简单回顾一下:

  1. 把 default.properties 复制为一个新文件,将新文件命名为 build.properties。
  2. 打开 first-shale/ 目录下的 build.properties 文件,对特定于您的系统的内容进行编辑。
  3. 在命令行提示符下键入 ant,从而使用 ant 构建应用程序。

添加到源代码树

前面已经提到过,您可以轻松地把自己的 JSP 添加到 Shale starter 应用程序的 src/web/ 目录中。该目录中的所有 JSP 都将自动添加到构建进程中。Java 源文件也是如此。src/ 目录中有一个名称为 java/ 的子目录。只需要把 Java 源文件放在该目录下,它们将作为构建进程的一部分被编译。

如果您还不太相信使用 Shale starter 应用程序的价值,构建进程应该能证明它非常有用。通过编辑单个文件 —— build.properties —— 您可以构建自己的应用程序,而且毫不费力。即使在使用 Ant(用于 Shale starter 应用程序的构建系统)时,也必须设置所有的目录、依赖项和构建 Web 应用程序需要的规则。但使用 Shale starter 应用程序,可以把时间精力用在编写 JSP 和 Java 类上,将文件拖放到正确的位置,键入 ant 即可。

当提到放置 Java 类文件时,通常来说,应使用与 Java 类的包结构相匹配的目录结构。例如,如果类名称为 Song,该类在包 com.nathanson.music 中,则应把 Song.java 文件放在 src/java/com/nathanson/music 目录结构中。这不会改变 Java 编译文件的方式 —— javac 只查看 Song.java 顶部的 package 指令 —— 但这是一种良好的代码组织结构。

源代码与二进制代码的对比

切记,源文件(或源代码)指的是 .java 文件而不是 .class 文件。通常,.java 文件称为源代码,已编译的 .class 文件则称为二进制 代码。Shale 的 src/ 目录是用来放置源代码的地方。target/ 目录(下面将予以介绍)是用来放置二进制代码的地方。

target/ 目录

只要运行 ant 并构建应用程序,就能看到一个名为 target/ 的新目录。该目录包含从 src/ 目录的源代码构建而来的所有文件。实际上,target/ 目录包含 “分解的 WAR”。WAR 文件只是 JAR 文件和一些额外的配置信息,以一种所有 Servlet 容器都能在里面部署应用程序的方式构建。如果取出一个 WAR 并展开它 —— 即解压缩,最终将得到 target/ 目录下的一个目录结构。(我马上解释 WAR 文件的实际创建方式。)

了解 Shale 应用程序源文件位置的最好方法是查看 starter 应用程序的 src/ 目录。同样地,理解一个已部署的 Shale 应用程序的形式的最佳方法就是查看 target/ 目录。首先,我解释在构建过程中 Shale 将各种文件放置在何处,然后为您演示如何设置它以部署应用程序。

target/ 目录内部

启动 Ant 后,打开已创建的新 target/ 目录。该目录下的内容如图 3 所示。


图 3. target/ 目录
target/ 目录

该图中很多内容看起来与在前面 图 2 中展示的 src/ 目录结构相似。像在 src/ 目录中一样,您可以看出标准 Web 应用程序结构,包括 Java 类和 JSP 页面。但文件顺序有些变化,而且增加了几项内容。

主应用程序目录

target/ 目录的所有内容几乎都位于名为 first-shale/ 的子目录中。如果您在 build.properties 文件中指定了一个不同的项目路径,在您的系统上该目录名称可能有所不同。不管它的名称是什么,清单 1 显示用于构建应用程序的文件:


清单 1. build.properties 文件示例
# Basic project information
project.copyright=My project, Copyright ?? 2006
project.name=My First Shale Application
project.vendor=IBM DeveloperWorks
project.vendor.id=com.ibm.dw

# Java package and context path for servlet engine
project.package=com.ibm.dw.firstShale
project.path=first-shale

# Directory for Shale distribution - change this for your system
shale.dir=/usr/local/java/shale-framework-20060204

# Directory for all your libraries - change this for your system
lib.dir=/usr/local/java/shale-framework-20060204/lib

可任选名称作为项目路径。Shale 构建脚本(使用 Ant)直接使用您为它在 target/ 下创建的目录所指定的名称。

manifest 文件

本文其余部分主要关注 target/ 目录中的内容 —— 但深入学习之前,您应该了解直接在 target/ 下创建的目录的内容。META-INF/ 目录只包含一个名为 MANIFEST.MF 的文件,如清单 2 所示:


清单 2. MANIFEST.MF 文件

Extension-Name: com.ibm.dw.firstShale
Specification-Vendor: The Apache Software Foundation
Specification-Version: 1.0
Implementation-Vendor-Id: com.ibm.dw
Implementation-Vendor: IBM DeveloperWorks
Implementation-Version: 0.1

将该文件的内容与 清单 1 和输入 build.properties 文件中的信息相比较,应立即能看出某种关联。MANIFEST.MF 从 build.properties 获得包名、项目供应商和项目供应商 ID,并把这些内容插入到该文件中。

使用 Shale 构建进程来构建部署到 servlet 引擎中的 WAR 文件时,该 manifest 文件将作为 WAR 的一部分包含进来,用它来确定内容。如果您使用任何 GUI 工具管理 servlet 引擎,这些工具能读取 MANIFEST.MF 文件并让您或其他系统管理员了解 WAR 中包含什么。

通常,不应该手动更改 MANIFEST.MF;实际上,如果需要修改它的值,则应该更新 build.properties 并且重新构建应用程序。如果您想独立地更改 MANIFEST.MF —— 而不更改 build.properties —— 然后重新构建项目,所有更改都将会丢失。通过使用 build.properties 控制 target/ 目录中的所有内容以及控制 src/ 目录中的所有内容,能够确保您的可部署的应用程序总是与开发完成的源代码和 build.properties 中为该代码编写的信息一致。

两个 META-INF/ 目录

实际上,在 target/ 结构下有两个不同的 META-INF/ 目录。target/META-INF/ 包含 manifest 文件,该文件用来创建整个 Web 应用程序的 WAR 文件。target/first-shale/META-INF/ 包含许可证和能提供一些关于 Shale 应用程序基本信息的说明文件。当心不要把这两个文件混淆。 它们虽然名称相同,但没有其他任何共同之处。

典型 Web 应用程序

如果您编写过任何类型的 Web 应用程序 —— 不管它是使用像 Struts 这样的框架还是单独编写 JSP 和 Servlet 代码 —— 应该已经熟悉了 Web 应用程序的基本结构。您在 target/first-shale/ 目录下能够看到同样的结构,看到像 META-INF/ 和 WEB-INF/ 这样的目录不应感到很惊奇。

包含在 src/web/ 目录下的所有 JSP 文件现在都放入 Web 应用程序的根目录中。您看 index.jsp、 welcome.jsp 和 messages.jspf — 在 src/web 目录下的三个 JSP 和 与 JSP 相关的文件 — 都直接位于 target/first-shale/ 目录下。

根目录(first-shale/)是所有 JSP 文件的所在;但若需要向应用程序添加更多的 JSP,不要 只是把它们放到该目录下。应该把附加的 JSP 放置在 src/web/ 目录下,然后重新构建应用程序。如前所述,Shale 编程(对于任何 Web 编程都一样)能实现的一个重要功能就是使源代码树和部署树保持同步。只要在 src/ 目录结构中进行所有更改,就不会有任何问题。

定位 Java 类

Java 类位于 target/first-shale/WEB-INF/classes/ 目录结构中。这是任何 Web 应用程序中 Java 类的标准位置,因此不应对它感到惊奇。您能在该结构中找到所有已编译的 Java .class 文件,这些文件嵌套在与包结构相匹配的目录结构中。因此在 org.apache.shale.blank 包中的 WelcomeBean 类文件,是位于 classes/org/apache/shale/blank 目录结构中的 WelcomeBean.class。

与源代码与二进制代码之间的分离相一致,在 classes/ 目录结构中没有 .java 文件 —— 这里不应该有!实际上,只有已编译的 Java 文件存在;像 JSP 一样,应该把新的 Java 源文件放在 src/ 目录中的 java/ 子目录下,并且让 Shale 构建脚本编译 Java 代码。

构建脚本还会把 src/java/ 目录结构中的属性文件复制过来;例如,target/ 目录中有 Bundle.properties(参考前面的 图 3),该文件位于 src/java/ 目录下。这允许您把 Java 类可能需要的文件与 Java 源文件放在一起,从而可在应用程序构建结构使用它们。

大量的依赖项

target/first-shale/WEB-INF/ 下的 lib/ 目录包含应用程序运行需要的所有库。前面已经提到,Shale 有大量的依赖项:

  • Java Runtime Environment (JRE) 和 Java Development Kit (JDK) 1.4 或更新版本(包括 Java 5.0)
  • Java Servlet API 2.4 或更新版本
  • JavaServer Pages (JSP) 2.0 或更新版本
  • JavaServer Faces (JSF) 1.1 或更新版本
  • JSTL (JSP Standard Tag Library) 1.1 或更新版本
  • Jakarta Commons BeanUtils 1.7 或更新版本
  • Jakarta Commons Chain 1.0 或更新版本
  • Jakarta Commons Digester 1.7 或更新版本
  • Apache Logging 1.0.4 或更新版本
  • Apache Ant 1.6.3 或更新版本

Shale starter 应用程序的一个重要特性是在构建期间它为您照管这些依赖项。现在不详细介绍这些依赖项的功能。您将在特定的编程任务或上下文中学习它们。但要注意,其余部 分的讨论假定您使用过 starter 应用程序并且已经拥有全部依赖项。如果您尝试从头开始构建 Shale 应用程序 —— 不使用 starter 应用程序作为模板 —— 则需要您自己添加所有的依赖项。这正是总是使用 Shale starter 应用程序开始开发的另一原因。

删除 JAR 文件

如果您不打算使用 Shale 的一些可选功能,可以删除特定功能的 JAR 文件。例如,如果您不打算将 Shale 与 Tiles 框架配合使用,可以删除 WEB-INF/lib/ 目录中的 shale-tiles.jar。但删除 JAR 文件没有任何好处(或许能节省一点点部署好的 WAR 文件中的空间),因此删除 JAR 文件不是一个好主意。保留这些文件可以保证在您确实 决定使用 Tiles 和任何其他需要 JAR 文件的附加功能时,能够满足需求。

在 starter 应用程序中,您在 WEB-INF/lib/ 目录下找到依赖项,它们均为 JAR 文件。同样,这也是 Web 应用程序中 JAR 文件的标准位置,因此不应该对它感到惊奇。您还能找到实际 Shale 库 —— shale-core.jar —— 以及几个使 Shale 能与其他框架(例如,Spring (shale-spring.jar)、Clay (shale-core.jar)、Tiles (shale-tiles.jar)和 Java 5.0 Tiger (shale-tiger.jar))协同工作的 Shale 插件。换言之,您已经拥有了使用 Shale 开发 Web 应用程序所需的所有库。这很容易,不是吗?

部署应用程序

我们已经编写好了源代码并构建了应用程序。完成这两步之后,所得到的结果是一个包含将应用程序部署到 servlet 引擎中所需全部文件的目录结构(first-shale/ 主目录下的 target/ 目录)。但是,保持所有这些文件并复制整个目录并不方便,也不安全。幸运的是,Shale 提供了一种部署应用程序的简便方式。

构建 WAR 文件

上篇文章介绍了 WAR 文件的构建方法,简要回顾如下:

  1. 打开 build.xml 文件,按 上一篇文章 中的介绍更改 “javadoc” 任务。
  2. 运行 ant dist

完成这些步骤,即可得到一个新目录,名为 dist/。该目录中的内容如图 4 所示:


图 4. 构建后的 Shale starter 应用程序
运行 Ant 后将创建一个新目录

这里最值得注意的文件是 first-shale-0.1.war,它是根据 build.properties(如前面 清单 1 所示)中提供的值命名的。dist/ 目录还包含与 Shale 和源代码相关的许可和自述信息。在您需要把整个应用程序移动到其他计算机上( 例如其他开发服务器或工作站)时,这使您可轻松地将整个 dist/ 目录打包为一个 ZIP 文件。但在许多情况下,您只会在一台计算机上开发应用程序,因此您最感兴趣的是 WAR 文件。

部署 WAR 文件

有了 WAR 文件后,实际部署应用程序是件很容易的事。获取文件并把它们放在 Servlet 引擎为 Web 应用程序提供的目录中即可完成部署。通常该目录的名称形式为 webapps/。然后 Servlet 引擎展开 WAR 文件(得到您在 target/ 中看到的目录结构)并部署应用程序。这时,就得到了可供使用的应用程序。





回页首


结束语

在本文中,我们剖析了 Shale 应用程序。您以一个 Shale 应用程序为背景学习了各目录的用途 —— 以及几乎每个目录下的每个文件 —— 从构建到部署应用程序。现在,您应清楚地了解了 Shale Web 应用程序源代码目录和最终展开的 WAR 文件的内容。

在阅读我的下一篇文章之前最好自行练习实践。如果您有一个想要将其转换为 Shale 的 Web 应用程序,那么完成它。从将其所有的 JSP 和 Java 文件移动到 Shale 目录结构开始。只需记住将所有的 JSP 放在 src/web/ 目录下,将所有的 Java 类嵌套入 src/java/ 目录中。随后即可构建并部署应用程序了。

的确,单纯的目录剖析与 Shale 组件的实际使用并不一样,但您在使用 Shale 应用程序基础设施,这是迈往正确方向的重要一步。(非常重要,所以我用一整篇文章解释 Shale 在何处放置源代码和部署形式的文件。)在下一篇文章中,我将进一步为您演示如何编写与 Shale 交互的代码。我将从 JSP 开始,然后介绍一些可以用于 JSP 页面的 Shale 相关标记。迄今为止,我介绍的还只是一些浅显的 starter 应用程序方面的知识。做出更改并完成们测试 —— 一定要使源代码树与部署树保持同步!





回页首


参考资料

学习
  • 您可以参阅本文在 developerWorks 全球站点上的 英文原文

  • 你好,Shale: Shale 不是 Struts”(Brett McLaughlin,developerWorks,2006 年 2 月): 开始使用一个完全新的采用 Struts 框架的方法。

  • Shale 主页:阅读 Javadoc 并找到有关 Shale 的其他框架信息。

  • Apache Struts:凭借自身的功能,它是 Shale 的 “父亲”,是常用的和可扩展的 Web 开发框架。

  • Apache Issue tracking Web 站点:获得 Shale 中的有关特殊 bug 的状态信息或有关特性的信息。

  • Java 技术专区:关于 Java 编程各个方面的数百篇文章。

获得产品和技术
  • 下载 Shale:开始使用 Shale 进行开发。

  • Apache Tomcat:一个了不起的 Servlet 引擎,能够与 Shale 和 Struts 很好地协作。

  • Apache Ant:一个用来构建 Shale 应用程序的基于 Java 的构建工具。


讨论




回页首


关于作者

Brett McLaughlin 的照片

Brett McLaughlin 从 Logo 时代就开始从事计算机工作。(还记得那个小三角吗?)近年来,他已经成为 Java 和 XML 社区最著名的作者和程序员之一。他曾经在 Nextel Communications 工作,实现过复杂的企业系统;在 Lutris Technologies 实际编写过应用服务器;最近在 O'Reilly Media, Inc. 继续撰写和编辑这方面的图书。Brett 在即将出版的新书 Head Rush Ajax 中,与畅销书作者 Eric 和 Beth Freeman 一起为 Ajax 带来了获奖的革命性的 Head First 方法。他最近的著作 Java 1.5 Tiger: A Developer's Notebook 是关于 Java 技术最新版本的第一本书。他撰写的 Java and XML 依然是在 Java 语言中使用 XML 技术的经典权威著作。


Comments:
This comment has been removed by the author.
 
Post a Comment

Links to this post:

Create a Link



<< Home

Archives

July 2006   November 2006  

This page is powered by Blogger. Isn't yours?