SQnote
永远有多远……
SQnote - java,web优化,python,(www.sqnote.cn)

作为软件开发人员,我喜欢设计和开发新的系统,但我不喜欢将时间花费在配置上。构建和部署weblogic应用会很快变得复杂。

每个被部署的单元,不管是EJB JAR文件、WAR文件或EAR文件,都需要在特定的目录下放置部署描述符。正确的类必须被包含进来,并且在正确的目录中。对一个公用类的改变可能需要对整个应用重新部署,在构建过程中的错误可能需要浪费几个小时来调试。
使用专有的IDE,对于单个开发人员来说,能够使构建过程自动化,但当试图部署其他人的工作成果时,可能会是一场噩梦。在市场上有好几种Java IDE提供自动化构建和部署WLS 应用的功能,但这些工具通常将构建和部署信息存储为专有的格式。
存储这些信息并将他们传递给其他开发人员使用是可能的,但它可能带来一些问题。首先所有个开发人员必须使用同一种工具工作;第二,一些工具保存所有的部署信息在单个文件中,使得保持单一拷贝的同步比较困难;第三,这些工具通常不提供高度的灵活性,使得部署到不同的服务器、部署多个组件、选择多个部署选项、脱离IDE部署组件都比较困难。


构建工具
Ant是一种专为Java量身订做的构建工具。Build和make工具已经有了多年历史,他们通常用于应用的自动化构建过程。它们通常会运行编译器、访问文件系统以及处理与构建应用相关联的各种其他任务。这些工具一般和操作系统结合紧密。它们使用专有的文件格式,很难编辑、容易出错。虽然很多make/build工具可以用来构建Java 应用,它们却不能提供操作系统的无关性,并且和Java的结合并不紧密。


为什么使用Ant?
Ant是Apache的Jakarta项目的一部分,它集成了java、javac、JAR、WAR和其他一些Java任务。它也支持多种文件系统任务,获得了操作系统无关性。在Windows下编写的脚本也可以在Solaris下工作得很好。如果Ant不能满足您的要求,您可以使用Java来扩展它。因为Ant是可扩展的,它几乎可以和很多东西集成,包括WLS。我将会展示如何集成Ant来完成WLS 应用的自动化构建和部署过程。有很多方式可以做到这一点,很难说那种方法最好,生成Ant 脚本是一个迭代过程,像好的代码一样,需要进行重构。我将集中说明如何使用Ant来构建和部署WLS应用。关于Ant的更多信息,可以在http://jakarta.apache.org/ant上找到。
Ant没有替换Java IDE,开发人员仍然使用他们熟悉的工具去开发代码和编写部署描述符,但当组件集成到要构建的项目中去的时候,应该包含一个Ant build.xml脚本。Build.xml是描述应用或组件构建和部署过程的xml文件。
使用Ant,您仍然需要做所有的配置工作,但是Ant将这个过程自动化了。Ant允许您使用XML定义自己的打包、构建、部署过程。XML文件成为一个活动的文档,开发组中的每个人都可以阅读和修改它,更重要的是每个人都可以执行它。这个过程可以通过更新XML构建脚本来不断求精。Ant使得快速执行复杂的令人厌倦的操作而不出错误成为可能。

如何开始使用Ant
在开始之前,要先建立运行环境。建立基于WLS的环境并不容易。对于WLS6.1,Ant已经包含在weblogic.jar包中。WLS现在包含Ant的构件脚本和一些例子。BEA在WLS的bin目录下有一个Ant的批处理和Shell脚本。换句话说,只要安装了WLS6.1,Ant自然也就安装了。假如您安装的是6.1以前版本的WebLogic 服务器,只需要从以下地址下载最新版本的Ant并且解压:http://jakarta.apache.org/ant/manual/install.htm。解压后在bin目录下有Ant的批处理程序和脚本文件。
让我们从一个例子应用程序开始。这个应用程序包括两个EJB:EJBOne和EJBTwo。EJBOne和它的helper类在mypackage.ejbone包里,EJBTwo和它的helper类在mypackage.ejbtwo包里。这个应用程序也包括一些servlet和JSP。这些servlet和JSP的helper类在mypackage.client包里。JSP页面文件、HTML和图片文件在content目录下。以下是这个例子应用程序的目录结构:

project/src/content
project/scr/mypackage/client
project/scr/mypackage/common
project/src/mypackage/ejbone
project/src/mypackage/ejbone/notneeded
project/src/mypackage/ejbone/META-INF
project/src/mypackage/ejbtwo
project/src/mypackage/ejbtwo/META-INF
project/src/ear/META-INF
project/staging
project/build


在WLS中使用Ant
项目属性
首先要做的是定义一个属性文件,虽然并不一定非得用。属性文件包含了一些在给定项目中的不同开发环境之间可能会变化的信息。下面是一个属性文件的示例。文件的命名没有关系,在这个例子中我们命名为config.properties.

WL_HOME=c:/bea/wlserver6.1

        STAGING=c:/project/staging

        BUILD=c:/project/build

        SOURCE=c:/project/src

        DEVELOPMENTSERVER= http://localhost:7001

        TESTERVER=http://testserver:80

文件中第一个属性是WL_HOME。WL_HOME因以下原因非常重要,首先,每个开发环境的WLS可能安装在不同的位置。第二,当您迁移到一个新版本的WLS时,您可以控制在构建过程中使用的是那个版本的WLS。下一个属性为STAGING.。它包含了部署前这些部件(如jar、ear、war)的位置。BUILD用来存储所有编译后的文件和临时文件。
DEVELOPMENTSERVER和TESTSERVER定义了不同服务器的URL地址,您可以将这些信息放在每个build.xml文件中,但是进行修改时非常麻烦。这没有充分利用属性文件的灵活性。每个开发人员可以有一个定制的属性文件,开发人员可能使用不同的开发服务器,甚至使用不同的操作系统,这些信息也可以放在ant.bat或ant.sh文件里面。
每个开发人员都有他们自己的一份拷贝,但是他们可能没有能力为每个应用定制,这些值也可以用命令行指定,但敲字比较麻烦。使用属性文件的根本原因是允许我们根据不同的开发环境和应用环境定制。


构建组件
下一步开始构建组件,我们从为EJBONE构建一个JAR文件开始。这个例子的第一行定义了脚本的基本信息。

<project name="EJBOne" default="deploy" basedir=".">

        <property file="../../config.properties"/>

默认的目标是在命令行中没有指定目标时将要运行的目标。我们等一会将详细地讨论目标。basedir定义了所有命令将要执行的目录。在本例中,我将xml构建脚本放在base目录中。我乐于这样做,因此每个组件都有自己的构建脚本,我将构建脚本和组件的源代码一起检入版本控制系统。所有开发人员都可以使用组件的源代码,执行Ant脚本,构建和部署组件。接下的一行包含了我们在清单1中定义的属性文件。在本例中我们将使用这些属性。

清单 1

 <project name="War File" default="war" basedir=".">

 <property file="../../config.properties"/>

 <target name="update_war" depends="compile_war,war">

 <java classname="weblogic.deploy" fork="yes"

 failonerror="yes">

 <sysproperty key="weblogic.home"

 value=""/>

 <arg line="-url update

 mypassword war /war.war"/>

 <classpath>

 <pathelement path="/lib/

 weblogic.jar"/>

 </classpath>

 </java>

 </target>

 <target name="compile_war">

 <mkdir dir="/war"/>

 <javac srcdir="" deprecation="on"

 destdir="/war"

 includes= "mypackage/client/**,

 mypackage/common/**">

 </javac>

 </target>

 <target name="war" depends="compile_war">

 <war warfile="/persdemo.war"

 webxml="/mypackage/client/

 web-inf/web.xml">

 <webinf dir="/mypackage/client/

 web-inf/">

 <patternset id="wls" >

 <include name="weblogic.xml"/>

 </patternset>

 </webinf>

 <classes dir="/war"/>

 <fileset dir="../../content/"/>

 </war>

 </target>

 </project>

编译
一个目标定义了一个工作单元。它可以从命令行指定或者定义为依赖于另一目标,下面的代码定义了目标compile_ejbone:

<target name="compile_ejbone">

        <mkdir dir="/ejbone"/>

        <mkdir dir="/ejbone/META-INF"/>

        <javac srcdir="" destdir="/ejbone"

        excludes="mypackage/client/**"

        includes= "mypackage/common/**,

        mypackage/ejbone">

        <classpath>

        <pathelement path="/lib/weblogic.jar"/>

        </classpath>

        </javac>

        <copy todir="/ejbone/META-INF">

        <fileset dir="/mypackage/ejbone/META-INF">

        <include name="*.xml"/>

        </fileset>

        </copy>

        </target>

编译目标负责编译EJBONE的类。首先我们调用MKDIR生成必须的目录。记住这些命令为操作系统无关的,这样脚本可以在任何环境下执行。创建这些目录后,我们可以编译代码了。
我们调用Ant任务javac启动javac 编译器。javac任务允许我们有选择地挑出那些包和Java类来编译。如果includes属性未被指定,所有source目录下的文件都被编译,excludes属性可以排除一些Java文件和包。
在这个例子中,我们需要编译包mypackcage.common和mypackage.ejbone中的所有类,除了 ExtraClass类和mypackage/ejbone/notneeded包之外。我们定义一个类路径来确保我们使用正确的WLS版本。最后我们拷贝部署描述符到build目录,这样他们就可以一并打包成jar。

构建一个JAR

下一步构建EJB的JAR文件,下面的代码使用Ant的核心任务JAR来构建初步的JAR文件,包含所有的编译类和部署描述符。

<target name="jar_ejbone" depends="compile_ejbone">

        <jar jarfile="/_ejbone.jar"

        basedir="/ejbone"/>

        </target>

jar_ejbone目标依赖于compile_ejbone目标。我们在编译类之前不能生成JAR文件。当jar_ejbone目标被调用时,首先要确保comile_ejbone目标被调用。如果comile_ejbone目标没有执行,它将在jar_ejbone目标执行之前自动执行。


运行EJBC

下面的XML 代码展示了如何在Ant中集成ejbc。这个目标依赖于jar_ejbone和compile_ejbone。依赖的次序不重要,因为jar_ejbone不可能在comile_ejbone之前执行,jar_ejbone不会执行两次,即使它被两个目标列为依赖。

<target name="ejbc_ejbone" depends="jar_ejbone,

        compile_ejbone">

        <java classname="weblogic.ejbc" fork="yes"

        failonerror="yes">

        <sysproperty key="weblogic.home"

        value=""/>

        <arg line="-compiler javac /_ejbone.jar

        /ejbone.jar -keepgenerated"/>

        <classpath>

        <pathelement path="/lib/weblogic.jar"/>

        </classpath>

        </java>

        </target>

目标ejbc_ejbone调用java任务。正如您所想的那样,这个任务执行一个Java应用程序。本例中这个应用程序就是weblogic.ejbc。Fork启动一个新的vm,有错误的话就会失败。如果ejbc编译过程失败,构建就会失败而终止。Failonerror属性只有在fork属性设为yes时才能设为yes。Sysproperty使我们可以为ejbc设置属性。接下来就为ejbc指定命令行参数。最后我们定义了类路径。


部署
现在我们已经生成了EJB JAR文件,我们要部署它。下面的update_ejbone目标看起来和ejbc_ejbone很相似,只是我们运行了weblogic.deploy。

<target name="update_ejbone"

        depends="ejbc_ejbone,jar_ejbone,compile_ejbone">

        <java classname="weblogic.deploy"

        fork="yes" failonerror="yes">

        <sysproperty key="weblogic.home"

        value=""/>

        <arg line="-url

        update mypassword ejbone /ejbone.jar"/>

        <classpath>

        <pathelement path="/lib/weblogic.jar"/>

        </classpath>

        </java>

        </target>

weblogic.deploy的参数行很有趣。首先,我们使用了config.para-meter文件中的DEVELOPMENTSERVER参数;这将部署URL设置为我们预先定义的开发服务器上。
接着,我们指定了weblogic.deploy执行的动作。接下来的参数是密码,因为我们没有指定一个用户名,默认为"system"。每次硬编码系统口令可不是好主意,后面我们将提供一个更好的解决方案。
最后,我们指定组件名和组件位置。现在我们键入c:nt update_ejbone,Ejbone将被编译、打包成jar、使用ejbc编译,并部署到开发服务器上。组件将被部署到中间阶段的目录而不是应用程序的目录。如果您以前在应用程序目录中安装过同样的组件,您应该删掉它。
另外,本例还演示了如何更新一个已部署的组件,生成一个安装新组件的目标是很类似的过程,我选择演示update因为我经常部署同一个组件,很少完全生成新的组件。


构建一个WAR包
我们已经了解了EJB,现在让我们创建一个WAR文件。在清单1中的Copy和Compile目标保证所有用来构建WAR包的文件都放在build/war目录。在war目标中要用到一个Ant预定义的任务war。我们也可以用jar任务,但是war任务能保证所有的文件在正确的目录中。Webxml属性指定web.xml部署描述符文件的位置,因为war任务并不只为WebLogic而设计的,所以我们必须手工指定weblogic.xml文件。webinf属性用来指定包含在WEB-INF目录里的文件。这里我们包含了weblogic.xml部署描述符。下一步我们要指定classes属性来定义类路径。最后fileset属性用来添加HTML、图像和JSP文件。

让大型应用的部署变得容易
如果一次将所有的组件都部署该怎么做?分开运行每个build.xml脚本文件很麻烦。我们可以为应用创建一个运行所有Ant构建脚本的Ant构建脚本。清单2显示了主build.xml脚本文件。这个脚本将应用中所有的脚本组合在一起。我们定义一个all目标,他本身没用具体功能,只是调用所有的依赖。Ejbone、 ejbtwo和war目标使用ant任务来调用其他构建脚本。这样我们就可以用主脚本来控制项目中的所有脚本。主构建脚本一般放在源程序的根目录下。进入那个根目录运行"ant"命令,这三个组件都会被部署。运行 c:nt ejbone war 将只部署EJBOne和WAR文件。

清单 2

 <project name="Master" default="all" basedir=".">

 <property file="./config.properties"/>

 <target name="all" depends="ejbone,ejbtwo,war"/>

 <target name="setup">

 <mkdir dir=""/>

 <mkdir dir=""/>

 </target>

 <target name="clean">

 <delete>

 <fileset dir="." includes=""/>

 <fileset dir="." includes=""/>

 </delete>

 </target>

 <target name="ejbone" depends="setup">

 <ant antfile="build.xml" dir="/

 mypackage/ejbone/" target="update_ejbone"/>

 </target>

 <target name="ejbtwo" depends="setup">

 <ant antfile="build.xml" dir="/

 mypackage/ejbtwo/" target="update_ejbtwo"/>

 </target>

 <target name="war" depends="setup">

 <ant antfile="build.xml" dir="/

 mypackage/client/" target="update_war"/>

 </target>

 <target name="ear" depends="setup">

 <ant antfile="build.xml" dir="/

 mypackage/ejbone/" target="ejbc_ejbone"/>

 <ant antfile="build.xml" dir="/

 mypackage/ejbtwo/" target="ejbc_ejbtwo"/>

 <ant antfile="build.xml" dir="/

 mypackage/client/" target="war"/>

 <mkdir dir="/ear/"/>

 <mkdir dir="/ear/META-INF"/>

 <copy todir="/ear" >

 <fileset dir="" >

 <exclude name="**/*.ear"/>

 </fileset>

 </copy>

 <copy file="/ear/META-INF/

 application.xml" tofile="/ear/META-INF/

 application.xml"/>

 <jar jarfile="/project.ear" basedir=

 "/ear/"/>

 <java classname="weblogic.deploy" fork=

 "yes" failonerror="yes">

 <sysproperty key="weblogic.home" value=

 ""/>

 <arg line="-url update

  projectname /

 project.ear"/>

 <classpath>

 <pathelement path="/lib/

 weblogic.jar"/>

 </classpath>

 </java>

 </target>

 </project>

 

主构建脚本文件中下一个目标是"ear"。这个目标构建一个EAR文件并将它部署到开发服务器上。这次当我们调用其他build.xml脚本文件时,因为不想作为独立的组件部署,我们指定ejbc和war两个目标。
下一步我们将application.xml文件拷贝到META-INF目录中,并且将所有文件用JAR打包进EAR。目标中的下一步是部署。通过加入一个参数来变更部署。现在密码不再硬编码写入脚本文件。运行脚本时,只需键入c:nt ear -Dpassword=yourpasswordhere,密码从命令行传入。
注意,当我们调用weblogic.deloy时,我们使用了"update"。这只能更新一个已经部署的组件。我们可以为新的部署增加另外的目标或者增加部署到不同服务器上的目标。我们甚至可以增加部署组件逻辑组的目标。主构建脚本文件提供了难以置信的灵活性。


结束语
现在您知道了如何使用Ant来构建和部署WAR、EJB和EAR文件到WLS上,以及如何使用一个主构建脚本来管理您的项目。您明白了如何通过修改主构建脚本来适应项目的特定挑战。这只是Ant如何改进您的开发过程的一个示例。
在项目中实现Ant时,您应该考虑为每个build.xml 生成一个clean目标,clean目标负责删除由build.xml文件生成的所有文件。EJB build.xml的公共部分可以移动到主构建脚本中,虽然我强烈建议对于每个EJB都将JAR文件的编译和构建放到一个单独的build.xml中。
试着将Ant集成到您的版本控制系统中。记住,我们自动化重复的任务越多,我们就能节约越多的时间。

本文原文URL: http://dev2dev.bea.com/technologies/ejb/articles/258.jsp

posted on 2006-03-09 15:10  SQnote·www.SQnote.cn  阅读(596)  评论(0)    收藏  举报