全部博文(2065)
分类: Java
2010-01-10 10:18:41
基于XML的远程过程调用Java API(JAX-RPC)定义了一套被用来开发访问网络服务(Web service)的接口,它有助于改善网络服务(Web service)的互操作性和可访问性。JAX-RPC能完全相容网络服务的异构特性–它允许一个JAX-RPC的客户端同部署在另一种平台并使用不同的语言实现的网络服务通信。同样,它也允许其他平台上用不同的语言编码的客户端与JAX-RPC 服务通信。JAX-RPC还定义了WSDL(Web Service Description Language)服务描述同Java接口之间的映射。
本文介绍JAX-RPC 技术并描述其客户端和服务器设计模型。JAX-RPC向使用Java 2平台构建网络服务的应用开发人员隐藏了下层协议和消息层处理的复杂性。这个API将XML 与远程过程调用 (RPC)相结合, 后者是使客户机可以执行位于分布式或远程系统上过程的机制,以使开发人员能建立网络服务和客户。JAX-RPC远程过程调用由一个XML信息集表示并通过网络传输. 虽然JAX-RPC APIs依赖一个基于XML的协议和网络进行传输, 但这些APIs本身是独立于特定的协议或传输的。目前JAX-RPC的实现依赖于 SOAP 1.1 协议和 HTTP 1.1 网络传输。
SOAP和WSDL是万维网联盟(W3C)所制订独立于语言的标准。SOAP是一个轻量的,基于XML协议的,在分散和分布式环境中交换信息的协议。SOAP协议的核心是一个SOAP封套(envelope)。这个封套定义了一个框架来描述消息中包括什么及如何处理之。SOAP定义了一套表示应用程序所定数据类型实例的编码规则。它制定了表达远程过程调用请求和响应的规范。SOAP规范还定义了一个传输绑定框架以利用下层协议交换消息。
WSDL用指定XML格式把网络服务描述为一组端点对消息的操作集。首先对操作和消息作出抽象的定义,然后将其绑定于一具体网络协议(HTTP)和消息格式(SOAP)从而定义一个端点(或端口)。相关联的端口和抽象端点组合也称为服务。WDSL用标准格式描述网络服务:它指定服务的位置和服务端口可见的操作。在网站能找到JAX-RPC参考实现的Early Access 2 (JWSDP EA2)版,包含可以分析现存WSDL文件或为网络服务生成WSDL文件的工具。
应用范例: SunReg 网络服务
本文用一个企业网络服务为例解释JAX-RPC概念和设计模型。这个企业网络服务的名称是SunReg,它允许一个单位的雇员们查询内部培训中心提供的各种课程并报名参加。SunReg允许雇员发送关于培训中心课程的查询。此网络服务提供给雇员每一门课程的相关信息,比如课程描述,授课地点,以及课程所需时间。雇员们也可以使用SunReg报名参加他们感兴趣的课程。雇员和课程的信息存贮在数据库中,图 1是SunReg网络服务的示意图。
SunReg应用程序的功能作为网络服务对单位内全体雇员都是可见的。雇员们用基于浏览器的客户端访问网络服务,象Java小程序(applet)或Java程序。此外,不同平台上的客户端能用不同的语言访问网络服务。 因为JAX-PRC遵守SOAP 1.1和WSDL 1.1标准使互操作性得以实现。
图 1. SunReg网络服务允许用户查找课程并报名参加。
SunReg是作为一个JAX-PRC网络服务端点来进行开发,部署,以及发布的。 一旦开发完毕,一个端点就被部署在支持JAX-PRC运行系统的容器中,该容器支持下层基于XML的协议和传输。网络服务端点可以作为基于servlet的端点部署于servlet容器或无状态的会话bean中。JWSDP提供了Tomcat作为servlet容器,在这里我们就用其作SunReg网络服务端点。JWSDP还提供了Java到WSDL映射工具,这个工具可以随同端点发布服务的描述。
一旦服务被部署并发布,客户即导入WSDL,典型情况是用WSDL到Java的映射工具生成调用服务端点的客户端工件。
关于本例中所使用软件版本的说明
本文中,我们使用的JAX-RPC参考实现来自开发与部署我们的网络服务的JWSDP EA2。JWSDP EA2中JAX-RPC实现是基于规范的0.7版。本文中的代码示例和文章写作时的JWSDP EA2版本兼容。JWSDP第一个面向客户的版本计划于六月中旬发布,它将编入最新的JAX-RPC规范。到那时这些示例中的代码就需要更新了;届时可以在这个站点查找关于应用程序移植的更新或建议。
还请注意整篇文章中我们提到的JWSDP安装目录都是JWSDP_HOME。
开发一个服务
如前所述,一个JAX-RPC服务端点便代表一个网络服务端点。当你准备创建一个服务端点时,你需要:
编写服务端点接口代码
从定义两个类开始。首先定义代表到服务的远程接口的类;即服务端点接口。它包含客户在此服务上可能调用方法的签名。服务端点接口扩展了java.rmi.Remote接口,并且它的方法必须抛出java.rmi.RemoteException。尽管每种方法都能抛出随服务不同而不同的异常,但我们为简化程序没有在文中的示例这么做。代码段 1是SunReg服务端点接口的源程序,程序名为SunRegPort。
代码段 1: 服务端点接口,SunRegPort
public interface SunRegPort implements java.rmi.Remote {
public Course[] getCourseInfo() throws
RemoteException;
public void registerCourseInfo(Employee emp,
Course[] courseArray)
throws RemoteException;
}
服务端点接口SunRegPort实现 java.rmi.Remote 接口,这是必需的。它提供了两个方法: getCourseInfo 和 registerCourseInfo。
雇员们使用getCourseInfo获得培训中心可提供的课程相关信息。也可以通过重载getCourseInfo增加一个提供搜索标准选项以便于查询的方法。
雇员们使用registerCourseInfo方法报名参加他们选择的课程。你可以配置registerCourseInfo来抛出服务指定的异常以指示该雇员被禁止注册某一门特别的课程。
代码段 1中的类Employee和Course描述了本网络服务中的实体:雇员和课程。 这些类定义为JAX-PRC的值类型。图 2展示了这两个类的细节。
图 2: Course 和 Employee JAX-RPC值类型
Course 和Employee 值类型根据JAX-PRC规范定义的JavaBeans模式而定义。值类型的所有成员变量声明为私有变量。每个成员变量的数据类型都为JAX-PRC所支持。每个成员变量都有一对getter和setter方法,这是依JavaBean设计模式定义的。
编写服务端点类代码
服务端点类提供了一个对服务端点接口所定义方法的实际实现。(你也可以把服务实现类叫做仆程序servant,象接下来我们称呼它一样)代码段 2是SunRegPort相应的服务实现类,其名为SunRegImpl。
代码段 2: 服务实现类SunRegImpl
import java.xml.rpc.server.ServiceLifecycle;
public class SunRegImpl implements SunRegPort,
ServiceLifecycle {
Connection dbConnection = null;
public void init(Object context) {
String dbUrl =
((ServletContext)context).getInitParameter("dbUrl");
dbConnection = DriverManager.getConnection(dbUrl);
//other relevant code
}
public void destroy() {
//release the database connection
}
public Course[] getCourseInfo() {
//get course information using the database
//connection
}
public void registerCourseInfo(Employee emp,
Course[] courseArray) {
//register for the course information using
//the database connection
}
}
类SunRegImpl包括对getCourseInfo 和registerCourseInfo方法的实现。(代码段 2 没有展示对两方法的实现,因为它们只与这个程序有关。)SunRegImpl 还扩展了java.xml.rpc.server.ServiceLifecycle接口,这也是定义一个服务的重要组成部分。
通过对ServiceLifecycle接口的实现,JAX-RPC运行系统管理服务端点对象的生命周期。SunRegImpl实现的init 和destroy 方法继承自ServiceLifecycle 接口。JAX-RPC运行系统调用init方法来初始化服务端点对象。服务端点使用init方法初始化它的配置并建立对任何外部资源的访问。init方法的参数context 使端点能访问下层JAX-PRC运行系统提供的端点上下文。JAX-RPC运行时调用destroy 方法决定服务端点对象不再处理远程调用。
举例来说,SunReg可以用init 方法传递的上下文获得一个外部资源的句柄。从代码段 2的SunRegImpl我们看到init方法取到了数据库的句柄。象数据库一类的外部资源在关联的web.xml文件中定义,我们会在后面的章节定义部署描述符中予以解释.
定义配置文件
接下来,你需要定义一个配置文件来生成各种JAX-PRC运行时必需的服务器端工件。配置文件指定一个(或多个)服务名及其端点的接口与类。我们的例子中配置文件名为config.xml,详见代码段 3,它遵循JAX-RPC规范,同时也指定了特殊的JAX-RPC实现。虽然其语法随实现的不同而不同,但配置文件都包含为xrppc工具所需的信息。
代码段 3: SunReg 配置文件
targetNamespace=""
typeNamespace="">
packageName="sunreg">
servantName="SunRegImpl"/>
来详细看一看配置文件中的重要属性:
定义部署描述符
因为我们想要把SunReg以WAR(网络归档文件)文件形式部署到JWSDP上,所以我们要给SunReg建一个web.xml文件。web.xml文件包含了有关部署此服务的关键信息,好像从服务到URL的映射,指出配置文件在WAR文件中的位置,及一些此类的信息。代码段 4是把SunReg服务部署在JWSDP容器时上用到的web.xml。
代码段4: 用来部署SunReg服务到JWSDP容器的web.xml
/WEB-INF/SunRegService_Config.properties
注意代码段 4中web.xml文件指定了dbUrl作为上下文参数,这意味着它的值将应用于WAR文件中定义的所有servlets。回调服务程序执行init方法(代码段 2的SunRegImpl中)便获得了上下文参数值以建立一个到数据库的JDBC联接。
servlet类JAXRPCServlet当JAX-RPC服务运行时可用,(即,它在目录JWSDP_HOME/common/lib下的 jaxrpc-ri.jar 文件中),它负责把来自桩(stub)程序的请求分派给容器内的关系-仆程序组合。关系-仆程序组合由_Config.properties 文件确定,在我们的例子中就是SunRegService_Config.properties文件了。_Config.properties文件被当作一个初始参数(init-parm)指定给servlet。Xrpcc工具生成该特征文件。文件名从config.xml中元素service的name属性推导而出。
最后,你为端点指定url-pattern属性。 这样就为网络服务决定了服务端点URL 。
编译服务
使用Java编译器编译服务端点接口和服务端点类。
然后通过给随JWSDP提供的Java到WSDL映射工具xrpcc输入配置工具,生成各种JAX-PRC所需的服务器端工件。必需的工件之一是WSDL服务描述。回调一个服务端点被映射为一个WSDL服务描述。WSDL文档用端口类型,操作,消息的抽象定义和实体协议绑定描述服务端点。
你将找到位于目录JWSDP_HOME/bin下的工具xrpcc 。通过此目录下的xrpcc.sh或xprcc.bat来执行。工具xrpcc生成桩,关系以及其它JAX-PRC运行时所需的客户端和服务器端工件。生成这个文件的命令是:
xrpcc.sh -both -keep -d classes config.xml
xrpcc选项的意义是:
或者,你可以通过指定 xrpcc 工具的-client或-server选项而非-both选项以只生成客户端或服务器端的工件。因为-client,-server和-both这几个选项是互斥的,所以你只能在xprcc工具中使用这几个选项的其中之一。
在xrpcc工具生成的各种工件中,桩(stub)和关系(tie)是最重要的。桩和关系是使服务端点和服务客户端之间能够通信的类。桩类在客户端,位于服务客户和JAX-PRC客户运行系统之间。桩类负责把来自JAX-PRC服务客户的请求转换为SOAP消息,并使用特定协议(我们的案例中是HTTP)将其发送到服务端点。它也把来自服务端点以SOAP消息形式接受的响应转换为客户需要的格式。把客户请求转换为SOAP格式称为marshalling;把SOAP格式转换为对客户的响应称为unmarshalling。同样,服务器端的关系类位于服务端点和JAX-PRC运行环境之间。关系类对服务端点类和SOAP格式之间数据作marshalling和unmarshalling。桩是担当服务端点代理的本地对象,图 3 对此作出解释。
图 3: JAX-RPC运行时和生成的类
除桩和关系以外,xrpcc工具为此服务生成它的客户端实现类,具体将在调用服务中解释。
xrpcc工具也生成一个特征文件把每个仆程序和生成的关系文件关联起来(在服务器端)。文件名是通过把_Config.properties附加到XML配置文件里service元素的name属性构成。每个服务元素有一个这样的特征文件。因此,对于服务SunRegService,xrpcc编译器生成文件SunRegService_Config.properties。
xrpcc工具还生成一个以标准格式描述此服务的WSDL文件。
尽管不建议编辑_Config.properties文件,但是可以这样做。我们在SunRegService_Config.properties加上一行以使得WSDL 服务描述能通过网络访问。我们把下面这行加到SunRegService_Config.properties的结尾处:
wsdl.location=/WEB-INF/SunReg.wsdl
这行使得我们的WSDL服务描述可以从服务端点访问而仅需简单地把?WSDL加到服务端点。注意当从端点访问WSDL时我们不得不把端口信息排除在外。我们还要确保SunReg.wsdl文件被包装成WAR文件放在WEB-INF目录下。
部署服务
一旦xrpcc完成它的工作,你必须包装此服务并部署其到一个servlet容器上(在本例程序中我们用Tomcat)。服务端点接口,服务端点类,和web.xml文件,与其它生成的工件和配置特征文件一并放进一个标准WAR文件(见代码段 5了解WAR文件结构示例)。因为我们希望SunReg 的WSDL服务描述能被服务端点访问,所以我们也要把SunReg.wsdl放进WAR文件。然后WAR文件被部署到servlet容器。成功的部署带来一个URL(端点),客户可以用其来访问此服务,在图 4中解释。
图 4: 部署服务和相关文件。开发人员写了两个Java文件,两个XML文件及客户程序。
注意还有些生成文件没有显示在图 4中。所有这些生成文件都被包装成WAR文件。对应SunReg的WAR文件的结构如代码段 5所示。
代码段 5:对应样例程序SunReg的web.xml WAR文件的结构。
META-INF/
META-INF/MANIFEST.MF
WEB-INF/
WEB-INF/classes/
WEB-INF/classes/sunreg/
WEB-INF/classes/sunreg/Course.class
WEB-INF/classes/sunreg/Employee.class
WEB-INF/classes/sunreg/SunRegPort.class
WEB-INF/classes/sunreg/SunRegImpl.class
WEB-INF/classes/sunreg/SunRegPort_Tie.class
WEB-INF/classes/sunreg/Course_SOAPSerializer.class
WEB-INF/classes/sunreg/Employee_SOAPSerializer.class
WEB-INF/classes/sunreg/GetCourseInfo_RequestStruct.class
WEB-INF/classes/sunreg/GetCourseInfo_ResponseStruct.class
WEB-INF/classes/sunreg/RegisterCourseInfo_RequestStruct.class
WEB-INF/classes/sunreg/RegisterCourseInfo_ResponseStruct.class
WEB-INF/classes/sunreg/GetCourseInfo_RequestStruct_SOAPSerializer.class
WEB-INF/classes/sunreg/GetCourseInfo_ResponseStruct_SOAPSerializer.class
WEB-INF/classes/sunreg/
RegisterCourseInfo_RequestStruct_SOAPSerializer.class
WEB-INF/classes/sunreg/
RegisterCourseInfo_ResponseStruct_SOAPSerializer.class
WEB-INF/classes/sunreg/GetCourseInfo_ResponseStruct_SOAPBuilder.class
WEB-INF/classes/sunreg/RegisterCourseInfo_RequestStruct_SOAPBuilder.class
WEB-INF/classes/sunreg/SunRegService_SerializerRegistry.class
WEB-INF/SunRegService_Config.properties
WEB-INF/SunReg.wsdl
WEB-INF/web.xml
在此web.xml文件中,SunRegPort_Tie针对的是关系类。而且,每个方法调用和响应建立为struct的模型(基于SOAP 1.1规范)。这样,xrpcc工具为每一方法在远程接口中生成了_RequestStruct和_ResponseStruct类。以_SOAPSerializer结尾的类被用来对值类型和结构作串行化和解串。以_SOAPBuilder结尾的类是被_SOAPSerializer类使用的辅助类。 SunRegService_SerializerRegistry 为 JAX-PRC 运行环境注册所有串行化类。
一个客户如何来访问SunReg服务呢?如果SunReg服务被包装成名为SunReg.war的WAR文件并且被部署在安装于主机howru 8080端口的servlet容器上,那么对一个JAX-PRC客户可访问端点的URL就是:
注意jaxrpc 来自在web.xml文件定义的url模式。当雇员在浏览器窗口访问此URL时,浏览器显示的消息如图 5所示。
图 5. 当用户访问浏览器的显示。
浏览器显示了在此端点支持的所有端口。每一端口映射为一个Java接口。这样,浏览器把SunRegPort当作在端点支持的端口显示:
/SunRegPort
服务的WSDL 描述可以通过点击“here”链接访问或可以通过下列URL找到:
调用服务
JAX-RPC网络服务端点对任何客户类型都可用,而不论客户使用的是何种语言或平台。服务客户使用以下的方法之一调用服务端点:
首先让我们讨论用基于桩的编程模型调用服务。与此模型相应的实现方式有两种。你可以执行xrpcc工具,使用-both选项或-client选项从服务端点接口生成桩。更通常的是,你可以通过用xrpcc工具导入已发布的服务描述,WSDL,来生成桩。
从服务端点接口生成桩
为了从服务端点接口生成桩,你可以调用xrpcc工具并用-both 或 -client 选项,一如前文在编译服务节所叙。
欲访问网络服务,你需要往客户程序中添加以下三行代码:
代码段 6给出一个例子。
代码段 6: 访问网络服务
SunRegPort_Stub stub = (SunRegPort_Stub)(new
SunRegService_Impl().getSunRegPort());
stub._setProperty(Stub.ENDPOINT_ADDRESS_PROPERTY,
"");
Course[] courseArray = stub.getCourseInfo();
正如我们前面讨论的那样,xrpcc工具为服务生成其客户端实现类。客户端实现类使客户能拿到服务端点的桩的句柄。xrpcc通过把_Impl附加到XML配置文件中服务元素的name属性来形成客户实现文件名。因此, SunReg 生成的客户实现文件名为SunRegService_Impl。此生成实现文件包括一个get方法,getSunRegPort,它返回对服务端点接口桩的引用。
取得对桩的引用之后,你调用桩的_setProperty方法以设定其端点地址。 Stub.ENDPOINT_ADDRESS_PROPERTY 指向javax.xml.rpc.service.endpoint.address。它是描述服务端点地址的属性。客户使用桩引用以调用服务上的方法。
当客户通过桩调用服务方法时,桩排列请求后放入一个SOAP消息并将SOAP包传送给部署于servlet容器上的JAX-PRC servlet。JAX-PRC servlet查看文件以找到合适的关系-仆程序组合,然后给这个关系-仆程序组合分配请求。方法响应沿同一路径返回给客户。
雇员可以浏览课程信息并可以调用桩的registerCourseInfo以选择课程。当雇员选定一门课程时,部署在容器上的服务程序使用已建立的数据库联接将雇员的选择信息存入数据库。服务程序还可以给雇员和他的经理发送有关课程日期和时间的电子邮件。
典型情况是,企业有一名系统管理员处理复杂的生成桩的工作并编辑配置文件。系统最终用户看见的是一个编排好了的图形用户界面,其中包括连到实际JAX-prc应用程序的链接。
如果权限能正确的设定则应用程序可作为applet运行。若要将程序作为applet运行,你必须给applet沙盒安全模型设置权限。如代码段 7所示。
代码段 7:设置程序使之作为applet运行。
grant {
permission java.util.PropertyPermission
"com.sun.xml.rpc.streaming.XMLWriterFactory",
"read";
permission java.util.PropertyPermission
"com.sun.xml.rpc.streaming.XMLReaderFactory",
"read";
};
从WSDL生成桩
因为SinReg的WSDL 服务描述已经发布,我们能通过导入WSDL到xrpcc工具来生成不同的客户端工件。要做到这点,你可以调用xrpcc工具并使用-client选项,此外还要提供一个配置文件。
因为网络服务已经安装就绪,从WSDL启动就不需要生成服务器端工件(例如关系文件等)。xrpcc工具不期待服务定义文件作为输入;取而代之的是它期待含WSDL文件相关信息的XML配置文件作为输入。在公共注册点发布的WSDL文件以标准格式描述了一个完整的网络服务。此外,WSDL文件还描述了如何访问网络服务;它包含服务的端口以及服务所在的端点。端口在WSDL就等价于远程Java接口(举例来说,当从服务端点接口启动时的SunRegPort)端点通常是访问WSDL文件中嵌入服务的URL。偶尔,端点可能是服务的URI(Uniform Resource Identifer统一资源标识)
请记住你并不需要了解WSDL的细节。一般说来,你用工具生成WSDL文件或解释生成好的WSDL文件。随JWSDP一并提供的xrpcc工具就是这样一个工具。
回到SunReg例子中来,当全体雇员们访问同一课程集时,从服务端点接口生成客户是最有用的。它便于单位里一些部门过滤出那些可为其雇员所选的课程集。要过滤课程,他们可以用xrpcc工具导入WSDL文件并生成桩文件。然后他们可以用这些桩对课程进行过滤。让我们看看怎么来做。
首先,假定SunReg服务已经被部署在一个基于servlet的容器上了,就象前面从服务端点生成桩章节描述的那样。端点已经发布而且我们已经把wsdl.location的名和值对加到 SunRegService_Config.properties 文件,使WSDL可以访问。(如果你需要复习这个技术,可参见上文的编译服务)现在,劳资部决定过滤给他们部门雇员的课程。要做到这点,劳资部的系统管理员取得由SunReg发布的WSDL文件,把它和XML配置文件一起交给xrpcc工具,见 代码段 8。
代码段 8: XML配置文件正文, config.xml
xmlns="">
location=""
packageName="sunreg" />
注意为从WSDL生成桩的config.xml
文件不同于从服务端点接口启动的配置文件。对于WSDL模型,配置文件指定了三部份信息: 使用这个信息,工具生成必需的客户端工件。注意WSDL可以通过location属性?WSDL的可访问性已经和正确的端点URL一起在WSDL的服务元素预先配置好了。 从客户程序的观点看来,在此网络服务上调用方法类似于由服务端点接口生成桩的模型。客户先调用语句new以新建一个由xrpcc生成的客户服务实现文件的实例。然后,客户用
getSunRegPort 方法取得指向该服务的桩引用。这步等价于取得一个指向远程接口的引用。因为端点包括在WSDL文件中,xrpcc工具生成随端点预配置的桩。这些预配置的桩意味着客户不必设置目标端点,而当客户从服务端点接口生成桩时这一步是必须做的。客户可以通过从方法getSunRegPort得到的桩引用来调用服务的方法。比如,客户调用stub.getCourseInfo: SunReg_Impl stub = SunRegIF_Stub(new SunReg_Impl()).getSunRegIF(); Course[] courseArray = stub.getCourseInfo(); 调用getCourseInfo返回所有SunReg提供的课程。劳资部的系统管理员可以过滤课程并为劳资部的用户提供新的界面。这展示了为目标受众调整现有网络服务的工作范围。 动态调用接口 有时侯xrpcc工具缺少必要的工具以分析WSDL并生成客户端工件。这种情况下,客户使用动态调用接口(DII)来替代。使用DII,客户能调用服务或某一服务远程过程而不必提前知道确切的服务名或过程的签名。利用能动态查找服务的服务代理及其远程过程,DII客户能在运行时发现这些信息。你可以参考Java Web Services Developer
Pack教程找到一个DII客户的例子。 结论 本文解释了一些基本的JAX-RPC设计概念。文章叙述了JAX-PRC客户和服务器设计模型并给出一些例子来讲解它们的用法。希望本文能较好地带给开发人员一个对如何应用JAX-PRC开发或使用网络服务的了解。 即将发表的一些文章会更深入探索JAX-PRC及相关课题。它们也将带给读者当前对JAX-PRC技术的改进。敬请发送你们的问题到。
更多信息 关于作者 Arun Gupta 在Sun Microsystems, Inc公司领导测试JAX-PRC实现。他自JAX-PRC项目始就在这个团队并且是技术进步的重要贡献者。Arun也在CORBA及其他Java分布式技术方面有所建树。你将发现他以jaxrpc-interes的绰号活动。 Beth Stearns 是ComputerEase Publishing的主要合伙人,这是她创办于1982年的计算机咨询公司。她的客户包括Sun
Microsystems, Inc.,Silicon
Graphics, Inc.,Oracle Corporation和Xerox Corporation。 她的作品有Addison
Wesley的Java系列丛书之“The Java Tutorial Continued”中的“Java Native Interface”一节,为Inprise Corporation写的“The EJB Programming Guide”以及Digital Equipment Corporation的文本编辑器使用教程,“Understanding
EDT”。最近,她正在与Vlada
Matena合著Addison Wesley的Java 系列丛书,“Applying Enterprise JavaBeans:
Component-Based Development for the J2EE Platform”。 Beth还对两本新近由Addison-Wesley出版Java系列丛书:“Designing Enterprise Applications with the J2EE Platform,
Second Edition” 和“The J2EE Tutorial.”有所贡献。