使用Ant和Weblogic开发EJB
无论是设计还是实施EJB,都是一件复杂的事情。仅在实施EJB的各阶段中要用的为数不少的应用服务器,就会使事情变得很糟。然后,如果我们使用BEA的Weblogic应用服务器再配合 http://jakarta.apache.org/ant' TARGET=_blank> Ant 就会使一切变得是那么的容易。
Ant是一个构造基于Java应用程序的开源工具,是Apache Jakarta工程的一部分。Ant使用XML作为构造描述语言,这种描述文件由一些有着有限状态的target组成,每一个target要么成功要么失败。开发者或者构造管理者定义各属性,在ant的配置文件中将各种任务转化成一系列target,并定义各target之间的依赖关系。在ONJava.com站点上通过http://www.onjava.com/pub/au/133' TARGET=_blank>David Thomson 写的http://www.onjava.com/pub/a/onjava/2001/02/22/open_source.html' TARGET=_blank> overview of Ant 我们可以找到更多的有用信息。
Ant的开发者提供一系列能够构造部署EJB的任务,一旦完成,就能够应用到weblogic4.5,5.1,6.0中,同样也能够创建可以在其它应用服务器中被处理的通用EJB包。只要通过适当的配置一个工程的ant文件,就可以使用<ejbjar>任务和<weblogic>元素等相似的五到八行XML语句构造出成百的EJB。
本文中是用Weblogic5.1作为服务器,但是只要精心设计,开发者或者构造管理者也可以使用其它的服务器,部署中的EJB和Weblogic任务标签是可扩展的。用户要特别关注的是,在下一个版本Ant 1.4中,它将支持iPlanet,Borland应用服务器以及Jboss。但是不支持在 nightly builds 上的Ant的一些可选任务以及其它的服务器。感兴趣的读者还可以从http://marc.theaimsgroup.com/?l=ant-user&r=1&w=2(search the Ant-user mailing lists)上找到关于Ant和EJBs以及iPlanet的更多的有用信息。
本文将分四个部份对使用Ant及Weblogic服务器开发EJB进行描述。第一部分描述怎样使用<ejbjar>任务及<weblogic>元素来配置一个工程。第二部分用实例讲述怎样在一个工程中部署构造一系列的EJB。第三部分教你怎样针对单个EJB来写一个Ant任务。最后,在第四部分中还会涵盖一些更为有用的可选功能,也有一些提示与技巧。
由于Ant使用自己的命名协定,所以可能导致与其它的EJB开发工具产生冲突。本文解决了一些已知的冲突。但是随着更多的工具的使用,将会有更多的冲突产生。在http://jakarta.apache.org/ant/manual/index.html' TARGET=_blank> Ant document.tion 上可以找到更多的有关在其它集成开发环境上使用Ant的细节。
命名模式
使用Weblogic的开发者要想使用Ant中<ejbjar>任务的强大功能,必需绕过一些陷井。实际上Ant配置文件中棘手的代码是很少的,也就那么七八行(不包含属性配置信息等)。一些有着几个月或者是几年经验的开发者们往往轻易的就开始了一个工程,但是他们却发现通过集成Ant却让事情变得更糟了。对于这些人,希望本文能给于他们足够的启发,让他们重新审视一下他们的工程,从而走出迷茫的误区。即使他们的工程将不打算使用Ant,设计一个好的工程结构对任何人在今后相当长的一段时间内都是有好的帮助的。
由于以前的EJB的例子及书籍(尤其是Monson_haefel’s的有关EJB的书)中的规定,下面的java类和模块命名惯例被开发者广泛使用。
• 执行类--<Bean名>Bean.java
• Home接口--<Bean名>Home.java
• Remote接口--<Bean名>.java
• 主键类--<Bean名>PK.java
鉴于以上所见,不能轻易的找到遵循任何命名协定和正当组织的部署描述符。局部来讲,这是由于容器把约束放置到描述符名上造成的,但是这可以通过脚本或简易EJB编译程序来解决。 Ant的 EJB任务需要好的组织来引导。没有一个标准的组织,EJB工程就会难以维持,同时随着工程的进展,描述符也会分散于整个文件系统中。Ant的模式为很多典型的无结构的java工程提供结构化。
在开始,我列出工程组织的一些关于使用<ejbjar>的规则:
所有的EJB类文件都必需遵循下面的标准的类命名规定,使用 bean名前缀。例如,不能用像IThumbMyNoseAtNamingConventions.java这种方式来命名,而是<Bean名>Bean.java这种形式。这虽然枯燥但却实用。
所有的EJB描述符都遵循这样的类名约定,在描述符前使用bean名作为前缀。
描述符协定并不像所说的那样严格。所有的描述符都以<Bean Name>开始(如:Account-ejb-jar.xml)。在Weblogic部署描述符中,容器管理的持久(CMP)的描述符名要求是明确的。但这并下要求有什么要改变,仅仅是文件名或者文件系统要遵循这个约定。在其它的一些章节我们也会讨论到这种潜在的命名协定冲突。
描述符从他们自己的目录使用bean名来得到每一个bean。
这条规则没有一二两点那么重要,便是它确实起到了良好的作用。
这些规则都不是必需的。
一些大的复杂的系统可能还要求一些当前的功能中不能满足的特定需求,或者有满意的需求但是本文却没有涉及到。对于这些项目,命名模式及工程布局可能没有应用。任何工程经过足够的努力都能使用<ejbjar>;使用这目经过规则会使<ejbjar>变得很简单。
布局
工程布局对于有效的编码及构造管理都是很重要的。创建模块化的文件系统组织会使打包及改动代码都很容易实现。Java的包系统就是这种设计概念的一个例子。在整个工程会议中概念图将受益于好的布局。在CVS或者其它的版本控制系统中管理代码会使问题更简单。
客观的说,如果不是这些约定,<ejbjar>任务就会变得像ant的其它任务一样,没有这样大的功能。工程越接近这些规则的需求,ant文件的代码就会越少。如果不遵循这一规则,ant文件就不得不描述及定义怎样来构造每一个EJB。使用这一约定,<ejbjar>任务就变得非常强大,而这却只需很少的工作量。
下面是一个工程布局的样例:
bigproject/
Java/
...
com/duffbrew/Account.java
com/duffbrew/AccountHome.java
com/duffbrew/AccountBean.java
descriptor/
...
Account/
Account-ejb-jar.xml
Account-weblogic-ejb-jar.xml
Account-weblogic-cmp-rdbms-jar.xml
build/
...
deploy/
Account/
Account.jar
doc/
lib/
这个工程构架遵循以上所有提到的规则。Account EJB 代码模块都被适当的命名。描述符文件在它们自己的目录中,也遵循代码模块的命名模式。
构造所有的EJB
下面就是<ejbjar>任务的大概样子。其中${weblogic.classpath}包含Weblogic需要的服务包、jar包及类目录。
<ejbjar srcdir="build"
descriptordir="descriptor">
<weblogic destdir="build/deploy"
classpath="${weblogic.classpath}:build"
compiler="javac"/>
<include name="**/*-ejb-jar.xml"/>
<exclude name="**/*weblogic*.xml"/>
</ejbjar>
八行代码就可以编译任意数量的EJB(在实际的ant文件中,还要有其它的一些属性要配置,所以实际代码行数会比这里的多。为了不浪费篇幅,本文已经明确的定义了这些属性。)。整个操作主要由两个主要的任务来完成 :<ejbjar>和<weblogic>。在document.tion列表中还有更多属性和嵌套元素,但是这里只需要上面这些就足够了。<ejbjar>构造通用的EJB,为指定容器的编译及部署作准备。<weblogic>在通用的EJB上运行weblogic.ejbc,为weblogic容器部署作准备。这里没有定义特定类和模块的属性。为了得到更好的性能,编译器属性要用Jikes替换成下面的样子:
compiler="jikes -nowarn"
Weblogic.ejbc将用到’no_warn’这个参数。由于它将Jikes传来的警告当作错误处理,这将有可能构造EJB失败。
通过这种方式,编译100个EJB所化的时间并不是简单的叠加。经验表明编译EJB是要化费大量的时间。这里的性能是非常好的。例如,编译一个有700个类文件和70个EJB的工程可以用不到100分钟的时间完成(在奔III800内存512M的机器上)。但是如果用javac命名编译同样的工程则要30到40分钟。但是在两种情况下,对单个类的编译都在30秒以下(jikes版本会化更少的时间)。
仅编译单个Bean
通过使用命令行或是属性文件中指定属性,就可以对指定的单个EJB进行编译。
<ejbjar srcdir="build" descriptordir="descriptor/${bean.name}"> <weblogic destdir="build/${bean.name}/${bean.name}.jar" classpath="${weblogic.classpath}:build" keepgenerated="true" compiler="javac"/> <include name="**/*-ejb-jar.xml"/> <exclude name="**/*weblogic*xml"/>
</ejbjar>
以上的代码片段已经说明了用<ejbjar>和<weblogic>来创建,编译以及放置一个EJB到${bean.name}指定的目录。利用这些简单的代码片段就能够不重新编译整个系统。应该注明的是静态依赖或者类似静态依赖的在整个依赖检查时不会考虑重新编译的。每次都重新编译整个系统是毫无益处的。
技巧与可选功能
描述符的差异
包括Weblogic在内的一些容器,更希望描述符遵循一个不同于ant任务所要求的那种命名协定。<ejbjar>考虑到这种内在关系,就重新命名并将它们