Maven 是一个软件项目管理工具,它能够管理一个项目生命周期中的构建、文档、报告、发布等。Websphere ApplicationServer Community Edition (简称WASCE)是IBM发布的一款免费的开源 J2EE 应用服务器。WASCE 构建在Apache 社区开发的 Geronimo 服务器的基础之上,提供了更广泛的硬件和软件平台的支持。在开发 J2EE项目时,代码的编译、单元测试、文档的生成以及把应用部署到 WASCE 是一个烦琐而且需要反复进行的过程。本文展示了使用 Maven来管理项目,自动化项目的构建和到 WASCE 服务器的发布,提高项目的开发效率。
Maven 是 Apache 开源社区开发的用于简化 Java 软件项目构建的工具,它是在 Java项目构建领域的成熟理论和丰富经验的基础之上,以高度重用的形式提供给开发者。Maven的目标是要使得项目的构建更加容易,它把编译、打包、测试、发布等开发过程中的不同环节有机的串联了起来,并产生一致的、高质量的项目信息,使得项目成员能够及时地得到反馈。
在使用 Maven 的过程中,会经常遇到以下概念,了解这些有助于更好的理解 Maven 的构建过程。
1. Project:Maven 把它所要构建的任何项目都称为一个 Project。此 Project 应该符合下面定义的POM模型。一个Project 可以依赖于另一个 Project;Project 还可以包含多个子 Project,子 Project 也是一个独立的Project。Maven 可以管理 Project 之间的各种关系。
2. Project Object Model(POM):POM 定义了 Project 的元数据。Maven 可以根据这些元数据来构建这个 Project。POM一般定义在 Project 根目录下的 project.xml 文件中。
3. Dependency:一般的 Java 项目在编译或运行时需要依赖于外部的包,在 Maven 中,这些包称为 Dependency。
4. Goal:Goal 是 Maven 中的执行单元,相当于 Ant 中的 task。每一个 Goal都对应于项目构建过程中的一个操作,例如:Java 程序的编译、web 应用打包。Maven 通过 Plug-in的方式已经提供了大多数需要经常使用的 Goal,但对应特定的项目,也可以在 maven.xml 中定义自己的 Goal。
5. Plug-in:Maven 是通过 Plug-in 来组织的。Maven 所提供的每一项功能都是通过 Plug-in来完成的。Plug-in 是可以重用的,它定义了 Goal,并且使用在 POM 中定义的 Project 元数据来执行这些 Goal。
6. Repository:Repository 用来统一存放 Maven 在构建项目过程中所依赖的外部的包文件。有两中类型的Repository:Local Repository 和 Remote Repository。Maven 在构建过程中,会检查 LocalRepository,如果没有所依赖的包,会去检查 Remote Repository,并且把此包自动下载到 Local Repository。
第一次接触 Maven 的开发人员一般都存在困惑:我们已经有 Ant 了,问什么还需要 Maven?我们可以从一个项目的开发、管理和构建过程来回答这个问题。
下面假设我们有一个项目为 SampleApp1,首先我们使用 Ant 作为构建工具,需要进行的工作如下:
1. 规划 SampleApp1 项目,包括用来存放不同资源的目录结果,需要使用的外部包文件等。
2. 编写 build.xml。在 build.xml中,项目的定义信息(比如目录信息和外部包依赖信息)和构建步骤混合在一起。这样的一个显著缺点是对项目 SampleApp2,build.xml完全没有可重用性。例如我们需要对一个 web 应用打包,就需要在 build.xml 中进行如下定义:
<target name="war" depends="init"> <war destfile="Filter.war" webxml="${filter}/WEB-INF/web.xml" compress="false"> <classes dir="${dest}"> <include name="**/*.*"/> </classes> <fileset dir="${filter}"> <include name="**/*.*"/> </fileset> </war> </target> |
3. 运行 Ant 构建项目。
下面我们再看使用 Maven 作为项目管理工具,需要进行如下工作:
1. 运行如下命令来生成可以用 Maven 来管理的项目 SampleApp1:
maven genapp |
此命令生成了 SampleApp1 的原型,可以在此基础上添加自己的资源。
2. 修改 project.xml。此文件只包含项目定义信息,比如目录信息、外部包依赖、测试信息、报告等。Maven plug-in可以根据这些信息来构建项目。对于上面例子中对 web 应用打包的操作,在 Maven 中有一个 plug-in可以完成此操作,我们不需要再重新定义,只需要调用如下命令:
maven war |
3. 运行 maven 构建项目。
从以上比较可以看出,主要的差别在第二步。Maven 通过 POM,把项目元数据和项目构建过程定义分离开来,使项目构建过程定义可以得到充分重用。可以认为 Ant 是"拷贝-粘贴"形式的重用,而 Maven 是通过 plug-in 方式实现了真正的重用。
除了重用性,Maven 还提供了其它特性,例如 Repository 机制,依赖管理等;而且还包含大量的可以重用的 Plug-in。
Geronimo 社区为了方便J2EE应用的开发和部署,开发了一套 Maven Plug-in,从而使得 Maven 可以用在基于Geronimo 的项目的整个构建过程中。WASCE 构建在 Geronimo 基础之上,所以这套 Plug-in 也完全适用于 WASCE。
Geronimo 部署 Plug-in 可以启动和停止 WASCE 服务器、部署和卸载一个应用、启动和停止一个应用。
这个 Plug-in 主要包含以下命令:
以上参数描述如下:
uri:用于连接到服务器的 URI。此 URI 采用如下形式:deployer:Geronimo:jmx://host:port。
username:连接到服务器的管理员的用户名,默认情况下是 system。
password:连接到服务器的管理员的口令,默认情况下是 manager。
module:要部署的应用的文件路径。
plan:要部署的应用的部署描述文件的路径,此参数为可选项。
id:所部署的应用的 configId。
下面我们将通过一个例子 Arithmetic Example 来展示 Maven 在 WASCE 开发中的应用。此例子的源程序在后面可以下载。
Arithmetic Example 是一个简单的计数器应用程序。为了只关注于 Maven 的使用,此应用只使用了 Servlet 和 JSP。此应用包括3个页面
图1是这些页面之间的流程图。
Maven 提供了一个名为 Genapp 的 Plug-in,它可以生成项目框架,简化项目的配置。运行此 Plug-in 时,它会询问用户一些信息,并且根据这些信息生成项目。主要询问的信息包括以下内容:
1. 要使用的项目模板。此 Plug-in 包括7种项目模板,经常用的包括默认模板、web 应用模板、ejb 应用模板、struts 应用模板。Arithmetic Example 使用 web 应用模板。
2. 此应用的ID。此 ID 用来表示生成的包文件的名字。
3. 此应用的名字。此项目的一个简单描述。
4. 此应用的包名字。指定此应用最上层的包名字。Arithmetic Example 使用com.arithmetic.example。
Maven 还提供了一个名为 Eclipse 的 Plug-in,它可以把 Maven 项目生成 Eclipse 工程。这样就可以利用 Eclipse 提供的强大的集成开发环境来开发我们的项目。
在生成 Eclipse 工程的过程中,可能需要从 Remote Repository 上下载一些本项目所依赖的包文件。
可以在 Eclipse 中把生成的工程导入进来,这时会发现有一些错误提示,这是因为生成的工程里用到了一个 Classpath 变量MAVEN_REPO,此变量指向 Maven 在本地机器上的 Repository 目录,在 windows 平台,此变量的值一般为C:\Documents and Settings\Administrator\.maven\repository。可以通过arithexample 工程的属性设置来添加此变量,如图2所示。
设置完 MAVEN_REPO,就可以在 Eclipse 中编写所需要的 Servlet 和 JSP 了。
Arithmetic Example 的构建过程主要包括以下几步:
1. 源程序的编译。
2. 打包成 WAR 文件。
3. 部署到 WAS CE 服务器。
4. 启动 Arithmetic Example 应用。
对应第一步和第二步,Maven 已经提供了相应的 Goal。第三步和第四步,需要使用 Geronimo 部署 Plug-in提供的命令来编写自己的 Goal。对于特定于某一个项目的 Goal 需要定义在此项目根目录下的 maven.xml 中,在 ArithmeticExample 的 maven.xml 中,我们定义了以下 Goal:
1. deploy:部署 Arithmetic Example 到 Geronimo 服务器。
2. start:启动部署的 Arithmetic Example 应用。
3. stop:停止部署的 Arithmetic Example 应用。
4. undeploy0:卸载部署的 Arithmetic Example 应用。
5. default:是一个默认 Goal,当运行 Maven 而不指定 Goal 时,将会运行此 Goal。此 Goal 将会编译源程序、打包应用成 WAR 文件、部署应用以及启动应用。
6. undeploy:此 Goal 停止 Arithmetic Example 应用,然后卸载此应用。
7. redeploy:此 Goal 先运行 undeploy,再运行 default。
<?xml version="1.0" encoding="UTF-8"?> <project default="default" xmlns:j="jelly:core" xmlns:u="jelly:util" xmlns:ant="jelly:ant" xmlns:velocity="jelly:velocity" xmlns:deploy="geronimo:deploy"> <goal name="default" prereqs="war,deploy,start"/> <goal name="undeploy" prereqs="stop,undeploy0"/> <goal name="redeploy" prereqs="undeploy,default"/> <preGoal name="java:compile"> <mkdir dir="${maven.build.dir}/xdoclet/webdoclet/WEB-INF" /> <attainGoal name="xdoclet:webdoclet" /> </preGoal> <goal name="deploy"> <deploy:distribute uri="deployer:geronimo:jmx" username="${geronimo.admin.user}" password="${geronimo.admin.password}" module="${module.file}"/> </goal> <goal name="start"> <deploy:start uri="deployer:geronimo:jmx" username="${geronimo.admin.user}" password="${geronimo.admin.password}" id="${module.configId}"/> </goal> <goal name="stop"> <deploy:stop uri="deployer:geronimo:jmx" username="${geronimo.admin.user}" password="${geronimo.admin.password}" id="${module.configId}"/> </goal> <goal name="undeploy0"> <deploy:undeploy uri="deployer:geronimo:jmx" username="${geronimo.admin.user}" password="${geronimo.admin.password}" id="${module.configId}"/> </goal> </project> |
联系客服