分类:
2008-09-12 13:11:05
Shale 不是什么?Shale 不是打包好的、有编制好的文档并经过严格测试的产品,也没有附带自动安装程序和优雅的管理界面。那么 Shale 到底是什么呢?Brett McLaughlin 在本文中将揭开这个 Struts 后代的面纱。在本文中,Brett 解释了 Shale 是什么,Shale 与 Struts 框架的不同之处,以及如何在开发环境中安装和设置它。
在过去 5 年间出现的所有 Web 框架中,Jakarta Struts 是 ™ 开发人员使用得最多的一种框架,因此其后代的问世是一件值得注意的事情。虽然 Shale 还不是最流行的框架,也不是最为人熟悉的框架,但是出自名门的背景仍给人以深刻印象。更令人兴奋的是,Shale 并不仅仅是 Struts 的重大升级和新的发行版:它彻底更新了 Struts 中的很多核心原则,并且加入了 Web 开发中最新的思想。
您将了解到,Shale 与 Struts 的背离是一柄双刃剑。一方面,Shale 是经过精心设计的 Struts 的后代。Shale 的创立者综合考虑了 Struts 的优点和不足,提出可与其前辈媲美的下一代框架。另一方面,正如您很快就可以在这个系列中看到的一样,Shale 是 一种完全不同于 Struts 的框架,其中隐含着很多新的开发工作!
Shale 不仅仅是 Struts 的又一个修正版,它已扩展到超出 Struts 所能达到的高度。它包含 Web 程序设计中一些最重要的、最近的开发成果,包括 JSP Standard Tag Library(JSTL)和 JavaServer Faces(JSF),并建立在这些开发成果之上。Shale 完全应该被看作是与 Struts 不同的一种框架,在这个系列中,我将还 Shale 框架以本来面目。在这个月的文章中,将首先对 Shale 与 Struts 之间的区别作一个概述,然后带您体验安装 Shale 并测试安装情况的步骤。最后,我将给出一些思想,令您能进一步参与到 Shale 项目(它是开放源码的)中,并提供一些相关的信息。整个系列的目的就是要向您展示如何安装 Shale 以及如何使用 Shale 构建和开发项目,同时很少涉及 Shale 的前辈,即 Struts 框架。
评价 Shale
任何新的 Web 开发框架要想在这个竞争已经很激烈的领域占得一席之地,最好能够经受住巨大压力下的评测。好消息是,Shale 独力经受住了细致的考察。但是,坏消息是,由于 Shale 完全是对 Struts 重新构建的产物,因此必须重新编写和重新测试您所有基于 Struts 的代码,以便实现这些代码。您将花同样多的精力来编写一个新的 Shale 应用程序,或将一个 Struts 应用程序转换成 Shale 应用程序,就好像 Shale 与 Struts 完全无关一样。
所以接下来我们忍不住要问,为什么还要采用 Shale 呢?为了得出答案,我首先解释一下 Shale 的伟大之处 —— 这在很大程度上是由于它的 Struts 血统,但这又不是惟一的原因 —— 然后讨论 Shale 之所以没有 被发布为 Struts 框架的重要修正版的两大原因。这样,您就会更好地理解从 Shale 身上可以得到什么,这将有助于评价使用这种下一代的框架是否值得。
Struts 血统
Shale 重用了大量的 Struts 代码基,并声称 Struts 是它的 “父” 框架,因此如果您要相信 Shale 的价值,就得相信 Struts 的价值。首先,Struts 作为第一个真正意义上的 Web 开发框架,拥有巨大的价值。据 Shale 和 Struts 网站报道,第一批代码是在 2000 年 6 月提交给 Struts CVS 库的,而Struts 1.0 是在 2001 年末才发布的。当很多开发人员正在艰难地使用 JavaServer Pages(JSP)和不断变化的 servlet 规范时,Struts 提供了一种易于使用的 Model 2 方法来构建基于 servlet 和 JSP 的 Web 应用程序。换句话说,Struts 使 Web 开发人员可以开发健壮的 Web 应用程序,而不必精于日志记录、分布式计算、JDBC、Servlet、JSP、JNDI、RMI 和 大量其他的 API 和技术。
接下来,Struts 要做的事情就是保持它的强大性:从写出第一批代码开始,Struts 连续 6 年一直是最流行的 Web 开发框架之一。至今它仍然是人们口中的谈资,笔下的素材,使用得不比任何竞争对手少。由于 Struts 是如此流行,如此长寿,如今它已经有丰富的功能,有良好的文档,被广泛地支持,并且易于使用,在它上面进行开发和管理也很容易。数千名开发人员对 Struts 邮件列表上的问题作出答复,数万名开发人员试用 Struts 并报告问题,这使得这些问题很容易得到修复。
最后,Struts 是不断发展的。很多框架一开始比较强大,然后就停滞不前(商业产品和开放源码项目都存在这样的现象),而 Struts 总是不断提供新的特性。当您 Struts 时,核心发行版中还包含一个健壮的确认引擎(validation engine),并且 Struts 已经与 JavaServer Faces 集成,拥有广泛的标记库和一个不断发展的 Model 2 架构,其中引入了在分布式 n-层应用程序领域中最新的思想。而且告诉您,Struts 还紧跟程序设计中出现的新模式,例如 IoC(Inversion of Control)。Struts 与 WebWork 和 Spring 框架自然地集成,后两者都是具有最佳血统的、为使用 Web 开发中的新方法提供入口的框架。
简而言之,您很难发现在 Struts 中有做不成 或不支持的事。所以显然我们就要问,为什么 Shale 要另起炉灶呢?为什么 Shale 没有成为 Struts 的下一个版本呢?这有两个主要原因:一个原因与鲜为人知的新软件发行惯例有关,另一个原因则与众所周知的 Struts 根基中的弱点有关。让我们分别来考虑这两个原因。
发行版辨析
要理解 Shale 为什么没有成为 Struts 的一个新的发行版,首先需要理解关于新软件发行的一两件事。对于一个新的软件发行版,大多数用户首先看的是一组新的特性。版本升级的幅度越大,用户对新特性的期待就越大。因此,如果软件版本从 2.1 升级到 2.2,就应该有一些新的特性,但是如果从版本 2.2 升级到版本 3.0,那么就应该有很多 新特性。这就是为什么当一些大型产品(例如 Microsoft Word)或操作系统(例如 和 Mac OS X )出了新版本的时候,用户总是对它们很挑剔。对于每一个新的发行版,用户总是期待有更多新的特性。
由于大多数用户一味地将注意力放在特性上,他们没有意识到向后兼容性(backward compatibility)才是真正最有价值的东西。虽然每个人都希望 Excel 中加入新的、很好的选项,希望 Panther 与 iTunes 有更好的集成,希望 Gnome 中对 XUL 有更好的支持,但是如果那些用户现有的程序和文件在新版本下突然不能运行的话,相信他们会尖叫,“这是血腥谋杀”。在这种情况下,新特性毫无价值。
对于 Struts 也一样。一般来说,Struts 的每个新版本都增加了新的特性,同时保持了与之前版本的向后兼容性。此外,新版本的 Struts 还需要支持旧版本的 Java 平台和 Servlet 规范,因为已安装的旧的 Struts 要在这些平台上运行。这两个需求 —— 向后兼容性和对旧版本的 Java API 的支持 —— 对于 Shale 来说已经是一个严重的约束。尤其是,至少就 Java 平台而言,JSF API 已经成为 Web 的中心组件。虽然 Struts 也支持 JSF,但是 Shale 却是完全依赖于 JSF 的 —— 这对于需要维持向后兼容性的 Struts 来说简直是不可能的。
最后,派生出一个像 Shale 这样的新项目,同时继续在 Struts 这种已有的项目上进行开发活动,这样做具有无与伦比的优势。如果 Struts 只是简单地升级到 2.0(或者 3.0 或 4.0),并在不考虑向后兼容性的情况下实现 Shale,那么对于很多人来说,由此造成的移植工作将是令人痛苦的,可能有人干脆连 Struts 也不再使用了。即使仍然维护更旧的代码基,也难于吸引开发人员花时间来修复 bug,他们也不愿意为一个 “遭到废弃” 的或者 “旧” 版本的软件增加特性。
由于这些原因,让 Shale 成为一个全新的项目,使其建立在一个新的代码基之上,是很有意义的。
Shale 的面向服务架构
Shale 之所以没有成为 Struts 的一个新的发行版,其最后一个原因与逻辑没有关系:而是与该框架将新方法接纳到 Web 开发中的能力有关系。Shale 在很多方面与 Struts 存在不同之处,其中有两点最为突出:
Shale 对 JSF 的依赖性具有深远的、令人惊讶的意义,而且大部分情况下是积极的意义。随着这个系列的深入,我将深入研究这些意义。在讨论其他方面之前,有必要对造成 Shale 与 Struts 之间差异的第二个方面进行详细的讨论。
如果您多次使用过 Struts,那么会意识到它很大程度上可以看作一个请求处理器,通过它可以接受请求,并指示框架如何处理请求。您可以指出采取哪种动作,使用什么模型,将哪种视图显示给用户,采用什么验证规则,显示哪种表单 ... Struts 是完全可以配置的。然而,所有这些的核心是一个请求处理器,为每个请求提供服务。这样的处理器是 Struts 中最重要、也是最复杂的部分,因为对于在处理一个请求的过程中涉及的所有工作,它都必须进行处理或托管,在 Struts 代码基中几乎没有哪一部分与这个请求处理器没有关系或不受它的影响。
因此,Struts 基本上难于作出改变。如果想修改处理请求的方式,或改变处理请求过程中各部分的顺序,那么将面临巨大的困难。实际上,不得不重新编写 Struts 代码基。更改请求处理器的行为倒是稍微可行,但是大部分是不容变动的。这是 Shale 试图解决的关键问题之一(如果您需要 Web 框架有那种程度的灵活性的话)。
Shale 没有像 Struts 请求处理器那样的中心组件,它只是一组数量很多的服务。可以自由组合这些服务,每个服务与其他服务之间是松散耦合的。通过一组良好定义的接口(有时候实际上就是 Java 接口类,有时候只是组件之间某种形式的契约),配置 Shale 的行为很容易。这使得 Shale 是可扩展的、灵活的,甚至是 “聪明的”。很容易更改它,不费吹灰之力就可以扩展它,并可以使它迅速适应新的编程方法。像这样松散地组装组件或服务通常被称作面向服务的架构,或简称 SOA。当然,这听起来有点儿玄乎,不过您大可不必因此而觉得 Shale 不好!
安装 Shale
可以从逻辑上和概念上理解 Shale 与 Struts 的不同之处,但是要想在脑海里弄清楚这两种伟大的框架有什么不同,则需要亲自动手去实践一番。很自然,每一种 Web 框架首先都需要和安装。不过幸好,在这个过程中通常可以了解到很多东西。那些安装和设置起来比较困难的项目和产品,通常也难于配置,难于在它上面进行部署,并且(最坏的情况)难于长久运行。虽然安装过程很难作为评价一个 Web 框架好坏的最可靠手段,但是至少肯定应该成为这个标准的一部分。在这一节中,您将学习手动地安装 Shale,对于一些难点有一定的体会,并了解为了使 Shale 运行,系统上需要些什么东西。
注意,我还提到了 Shale 的 简便安装 选项,但是我强烈建议您至少试一试手动安装,了解它提供的较深层的信息。
先决条件
Shale 的先决条件和需求相当多。和大多数与 Apache 和 Jakarta 相关的项目一样,Shale 的安装要依赖于一些其他的 Jakarta 项目。下面是为了使 Shale 得以运行所需的所有东西的完整列表:
Apache Ant 只是在构建 Shale 时要用到,但是无论如何,如果您要进行较多的 Java 开发,那么系统上还是需要(很可能已经有了)一个版本的 Ant。如果想跟踪 Shale 中的 bug,那么需要 FindBugs 0.8.5 或更高版本和 JUnit 3.8.1 或更高版本。由于在第 1 部分中我只是讨论 Shale 的安装和使用,因此您还不必关心 FindBugs 或 JUnit,除非您想早点儿装上这两个项目。
附件和它们的依赖项
和 Struts 一样,Shale 还有一些附件(在 Shale 中常被称作可选 Shale 组件),这些附件各自又有其依赖项:
如果说这份列表显得有些长并且令人生畏的话,那么没错!Shale 使用大量较低级的库、helper 类、实用程序组件和来自其他项目的类。如果必须逐个安装这些组件,配置 Shale 使用它们,并将所有这些组件组装成可以部署的某种形式的话,即使是最专业的开发人员也会对 Shale 望而生畏。此外,由于 Shale 在它的开发圈子内仍然相当年轻,对于这些依赖项的获得和配置仍然有些稚嫩;然而,Shale 确实是非常可行的,而且不需要花费您想象中那么多的精力。
首先,如果您正在用某种框架从事某种 Web 开发,那么应该已经有了一些作为依赖项的项目。所以这份列表比它初看上去要容易管理得多。例如,任何 Web 开发人员都应该已经有 JRE 和 JDK,也应该有一个 servlet 引擎,例如 Jakarta Tomcat。如果已经有一个 servlet 引擎,那么也应该有 Servlet API 和 JSP 引擎。另外,大部分 servlet 引擎(至少就当前版本而言)都包括一个 JSTL,并且很多都附带了 JSF。最后,大多数开发人员很可能在他们的机器上已经安装了 Ant。因此,这份列表很快就只剩下这些了:
考虑到 Tapestry 实际上提供了将它的所有依赖项附带的选项,因此 “太多依赖项” 的问题很快就不成为问题了。
现在您已经知道了大概,现在我们来看看下载、安装和配置 Shale 及其依赖项的步骤。
1. 下载 Shale
要下载 Shale,可访问 Shale 项目主页。您可以看到一个 “Shale Download” 区域,其中有 Shale 框架的每晚构建的链接。单击这个链接,便可以进入如图 1 所示的一个站点:
图 1. 来自 Shale CVS 库的每晚构建
为了使 Shale 运行,需要下载 “framework” 文件和 “dependencies” 文件。例如,在撰写本文时我下载了以下两个文件:
当然,如果您需要或者更愿意下载 .tar.gz 版本,那么可以不选择 .zip 版本,而选择 .tar.gz 版本。由于 Shale 的开发还在进行中,目前还没有发行的构建,因此您应该尽量下载最近的每晚构建(具有最近的日期)。
下载完这两个文件后,首先解压这两个归档文件。对于核心框架,解压后可以得到一个具有形如 shale-framework-20060204/ 的名称的文件夹;对于 dependencies 归档文件,解压后可以得到一个名为 lib/ 的文件夹。将核心框架目录 shale-framework-20060204/ 转移到您希望保存 Java 项目的地方。例如,在我的系统上,我将 shale-framework-20060204/ 移动到 /usr/local/java 目录中。接下来,将 lib/ 目录移动到 Shale 目录中,所以最后的目录结构与 shale-framework-20060204/lib/ 类似。
2. 添加 Shale 库到 Web 应用程序中
下一步是将所有 Shale JAR 文件和库添加到 Web 应用程序可以访问和使用它们的位置。步骤如下:
1. 如果在 servlet 引擎中没有包含 JSF,那么将 shale-framework-20060204/lib/jsf-ri/jsf-api.jar 和 shale-framework-20060204/lib/jsf-ri/jsf-impl.jar 复制到应用程序的 WEB-INF/lib 目录中。
2. 将 shale-core.jar、shale-clay.jar、shale-tiles.jar 和 tiles-core.jar 从 shale-framework-20060204/dist/ 目录复制到 Web 应用程序的 WEB-INF/lib 目录。
3. 将以下 Shale 依赖项复制到 Web 应用程序的 WEB-INF/lib 目录:
4. 如果要使用 Shale 的 Spring 集成特性,那么将 shale-spring.jar 从 shale-framework-20060204/dist/ 复制到 Web 应用程序的 WEB-INF/ 目录。要完成这个步骤,还必须确保 Spring 的打包 JAR 文件也在 Web 应用程序的 WEB-INF/lib 目录中。这个 JAR 文件名为 spring.jar,如果您还没有这个文件的话,可以在 shale-framework-20060204/lib/shaleframework/ 目录中找到它。
5. 如果正在使用 Java 5.0,那么将 shale-tiger.jar 从 shale-framework-20060204/dist/ 复制到 Web 应用程序 的 WEB-INF/lib 目录中。只有在使用 Java 5.0 的时候才需要执行这一步;否则,servlet 引擎和使用 Shale 的 Web 应用程序就会出问题。
再往后走就开始复杂起来(是的,这些复制操作是较容易的一部分)。接下来的事情未必都要用最难的方式去做,至少我应该让您有机会选择 试试容易的方法。使 Shale 在系统上运行这个任务的确存在捷径;您已经知道手动设置 Shale 的过程比较复杂,接下来有必要看看 “简便” 方法。
更容易的方法
重新访问 Shale 下载站点,并下载名称类似于 shale-starter-20060204.zip 的 “starter” 应用程序。解压这个归档文件,将得到一个名为 shale-starter/ 的目录。这是一个基本上配置好的 Shale Web 应用程序,用于帮助避免前一节详细介绍的复制和配置工作。首先要做的是将 shale-starter/ 目录重新命名成应用程序以后要使用的名称,例如可以将它命名为 first-shale/。进入 first-shale/ 目录,在这里可以看到一些文件和子目录。
在 first-shale/ 目录中,创建一个名为 build.properties 的新文件。通过这个文件可以定制如何构建 Shale starter 应用程序,并确保该应用程序适合您的环境设置。清单 1 展示了一个基本的 build.properties 文件,可以根据自己的环境对其进行定制。
清单 1. Shale starter 应用程序的示例 build.properties
# Basic project information # Java package and context path for servlet engine # Directory for Shale distribution - change this for your system # Directory for all your libraries - change this for your system |
根据系统设置好这些属性后,便可以运行 ant。Shale starter 应用程序开始构建 并(假设已经正确地设置了路径)创建一个示例应用程序。如果有问题,则构建脚本输出错误消息;这些错误消息都描述得很清楚,所以您应该可以更正任何错误。
构建过程的最后将生成一个名为 target/ 的新目录。进入这个目录,可以看到一个名为 first-app(即您在 build.properties 中为项目指定的名称)的子目录。大多数 servlet 引擎都允许将这个目录整个地复制到 servlet 引擎的 webapps/ 目录。例如,我使用的是 Tomcat,于是我将构建脚本创建的整个 first-shale 目录复制到 /usr/local/java/tomcat/webapps。
[1]