没有合适的资源?快使用搜索试试~ 我知道了~
106《理论计算机科学电子札记》65卷第4期(2002)网址:http://www.elsevier.nl/locate/entcs/volume65.html11页元编程在Web构件部署中的应用WelfLéow e1MSI,软件技术。瓦若大学集团Véaxjéo,Sweden马库斯湖野贺2号IPD,Program StructuresGroup卡尔斯鲁厄大学卡尔斯鲁厄,德国摘要元编程是许多文章中描述的通用方法。令人惊讶的是,成功应用的例子很少。本文给出了这样一个例子。通过少于2500行的元程序,我们通过添加特定的基于XML的通信设施在Web上部署组件这强调了元编程方法的表达能力。1介绍元编程是一个模糊的术语。在本文中,我们使用以下概念:元编程将源程序解释为要分析和转换的数据。根据其应用的时间,我们区分静态和动态元编程。前者在编译时执行分析和转换,后者在运行时执行。元编程的思想并不新鲜:它是冯·诺依曼计算机体系结构的直接结果。早在20世纪50年代,Lisp 1.5[7]统一处理程序和数据项。两者都可以在运行时被接收和转换。这个动态元编程的实例是通过简单地解释所有代码来实现的。1 电子邮件:Welf. msi.vxu.se2电子邮件:markus@noga.de2002年由ElsevierScienceB出版。 诉操作访问根据C CB Y-NC-N D许可证进行。洛维和诺加107最近,对元编程的兴趣又重新燃起。原因之一是Java编程语言及其允许动态代码分析的反射接口的成功。另一个是需要重新设计大型遗留代码库。最后但并非最不重要的是,软件工程越来越多地旨在重用预定义的组件。由于这些组件被定义为尽可能广泛的重用,部署应该使它们适合任何具体的环境。这种部署可以通过元编程自动化有很多元编程工具。他们中的大多数都专注于方面编织或重构。因此,它 们 的 用 户 不 能 设 计 新 的 元 程 序 。 遵 循 这 一 规 则 的 有 Puma[1] 、Transmogrify[2]、设计维护系统(DMS)[3]和安装程序[6]。除了语法分析器之外,所提到的系统在其解析和语义分析阶段的通用性方面受到限制。Objecder为Java提供了一个完整的编译器前端,并可以访问所有分析过的语法和语义信息虽然元编程的必要性是无可争议的,支持工具也已经开发出来,但文献并没有报道许多实际应用。出版物解决了手头的元编程的具体问题,或者专门讨论应用程序方面,将元程序留给读者的直觉。本文件旨在弥补这一差距。作为元编程的一个示例应用程序,我们讨论了通过添加基于XML的通信设施在Web上部署组件尽管我们只部署Java组件,并且我们的元程序使用编译器,但我们避免利用Java规范,例如语言反射接口。因此,我们的方法可以推广到其他语言和工具。本文的组织如下:我们首先在第2节中讨论案例研究的领域。在第3节中,我们提出了一个合适的软件体系结构的域。然后,我们在第4节中使用元编程生成一致性实现。最后一节,5,总结了我们的结果,并概述了未来的工作方向。2案例研究领域Web服务是一个热门话题。本质上,Web服务是一个支持远程方法调用的类。调用数据以XML编码[13],通常通过HTTP传输[4]。可接受的调用消息集可以用DTD或XML Schema指定[14,15]。这个基础是有吸引力的,因为它独立于平台和语言,基于开放标准,人类和脚本语言都可以理解,因此很容易适应。次要的考虑因素,如隧道企业防火墙的能力,仍然是激烈的争论,并被视为一个主要的好处或一个主要的安全隐患。更高级别的Web服务标准,如SOAP和WSDL [11,12],更详细地定义了方法调用格式和接口规范。不幸的是,SOAP和WSDL符号都非常麻烦,洛维和诺加108MyImpl打印空间大。因此,出于本文的目的,我们将自己限制为纯XML服务,其接口由DTD描述。我们也忽略了寻址问题,使用直接套接字连接。这些限制都不是元编程方法所固有的。在生产代码中,它们很容易被消除。如何实现Web服务?Java [5]是当今教育语言的首选。由我们的研究小组开发的元编程系统,Jumder[6],在Java程序上运行,并且本身就是一个Java程序。因此,在本案例研究中,我们将重点放在部署基于Java的Web服务上。要做到这一点,我们需要一个模型来说明究竟要部署什么我们将组件类(或短组件)与辅助类区分开来:组件对象的方法可以远程调用,而辅助对象的方法调用总是本地的,即调用者和被调用者运行 在同一个地址空间。当调用组件方法时,组件对象通过引用传递,而辅助对象通过值传递远程调用必须保持多态性以保证位置透明性。此外,传递给组件方法的参数和组件方法的返回值通常都是复杂的对象图,可能包含自行车.为了消除Java中无法重定向的成员变量访问,我们遵循Java组件传统[10,9],将组件指定为两部分:指定允许操作的接口必须继承一个组件标记接口,以将它们指定为组件接口(见图10)。①的人。我们也可以用任意的元程序来指定组件边界,而不是使用接口继承的语言特性。的«界面»组件«界面»MyComponent+m1()+m2()图1.一、A组件规格洛维和诺加109这种方法对于将遗留系统组件化很有用。在本演示中,为了简单起见,我们使用组件标记接口。现在我们可以精确地定义应用程序问题:给定一个如上所述的组件,将其部署为Web服务。这可以分解为两个子任务。首先,添加允许位置透明访问的基于XML的通信工具。第二,生成XML Web服务描述,即,DTDs如上所述下一节将讨论处理基于XML的通信的软件3架构在典型的构件体系结构(如CORBA [8])的模型中,我们使用存根/骨架模式进行远程构件访问。存根实现组件接口。它在客户端的地址空间中运行,并通过网络传递所有方法调用,接收返回值。骨架在服务器地址空间中运行。它解码传入的消息并调用组件类的适当方法,通过连接传递返回值。为每个组件生成特定的存根和骨架。图2显示了所涉及的类。由于传递返回值与传递参数是对称的,因此我们在本演示中重点讨论传递参数。详细地说,存根是组件类的代理。它将方法调用转换为一个XML元素,该元素封装有问题的方法、组件对象引用和辅助对象值。组件对象引用可以很容易地由«界面»MyComponent+m1()+m2()图二、部署的组件。左边的类在客户端上运行,右边的类在服务器上运行生成的类以灰色显示。我的骨架MyImplMyStub«界面»组件«界面»骨架+handle()洛维和诺加110单个元素,但辅助对象值可能非常复杂。然而,给定将辅助类映射到元素的序列化器,方法只是映射到包含固定参数元素序列的元素辅助对象的序列化程序将辅助对象映射到文本元素,文本元素包含所有成员变量的序列。在这里,基本类型直接映射到XML元素。组件对象映射到包含URI引用的元素。辅助对象被递归映射到文字。这导致了对可访问对象图的深度优先遍历,其中组件对象被视为叶子。对于这种遍历顺序,对象图中的所有循环都表现为后向边。可以通过维护一组已经序列化的对象虽然可以为所有序列化对象提供类型ID的显式属性,但这种方法会产生存储开销,即使对象不是后向边缘的目标,除非两遍序列化采用了相反,我们只是在深度优先序列化中使用对象的唯一索引来引用它们。序列化和非序列化期间的对称簿记使这两个操作都是单次通过的。通过普遍允许反向引用元素代表文字元素,循环对象图可以准确地映射到XML。相比之下,在当前的Microsoft .NET原型中,序列化并不知道这个概念。它可以在运行时检测周期,但无法处理它们。现在,让我们考虑序列化器的软件架构。生成的XMLSerializer类为每个辅助类、数组和接口包含一个静态序列化程序方法.这些序列化程序方法的目标是一个不变的XMLSerializerStream对象。它的类封装输出流和已经序列化的对象集它包含方便的方法来串行化原始类型,向后引用和空值(表示为对第零个对象的为了访问私有成员变量,必须将两个序列化帮助器方法织入辅助类。因此,静态序列化程序可以使用多态方法调用来解析动态类型。例3.1假设以下辅助类定义:抽象类A{ inti;A a;}接口B{}classCextendsA{ float f;B b;}classXextendsCimplementsB{X x;}classY extendsX{ boolean[] b;}类Z实现B{Xx;}在XMLSerializer中为Y生成以下方法:publicstatic void online(online,online){ if(online,online)}洛维和诺加111返回;o.serializeXML(s);//o可以是类型Y或其}静态序列化程序以多态方式调用数据类型序列化程序,继而单态地调用数据布局串行化器。在使用适当的静态序列化程序序列化自己的字段之前,数据布局序列化程序单态调用超类数据布局序列化程序来序列化继承的成员变量。这种多阶段分派具有显著的运行时灵活性。相反,Microsoft .NET原型中的序列化仅限于静态指定的数据类型。可能的子类必须由用户枚举。换句话说,在添加新的子类之后,整个类层次结构中使用超类的所有方法都必须手动更新。例3.2(续例3.1)这些方法被添加到类Y:public void serializeXML(XMLSerializerStreams){s. println(“println”);“/classY>”); document.writeln(“/classY>”);}protected final void serializeBodyClassY(XMLSerializerStreams){//超类数据布局serializeBodyClassX(s);//boolean[]b;XMLSerializer.serializeArrayOfBoolean(s,this.b);}为了说明序列化器的操作,考虑构建的对象图从图3所示的例3.1中定义的类。例3.3显示了类Z的实例的相应序列化。例3.3(续例3.1,3.2)图3.2中Z实例的注释序列化3.第三章。<!-- ID 1--><!-- ID 2内容的 X-->42/int><!--值内容的 我--><参考>2/参考><!--参考内容的 一 --><浮动>3.1415/浮动><!--值内容的 F--><参考>0/参考><!-- null内容的 B--><参考>2/参考><!--参考内容的 X--> <!-- ID 3内容的 B-->false/boolean><!--值内容的 联系我们true/boolean><!--值内容的 b[1]-->false/boolean><!--值内容的 b[2]-->洛维和诺加112int length=3{false,true,boolean[]int i= 0A a=浮点数f=3.1415 Bb=x= boolean[]b=舱YnullX x=类Z图3.第三章。一个示例对象图。 <联系我们<联系我们/classZ>让我们回到图2。到目前为止,我们省略了骨架操作的细节。骨架是存根的逆:它从传输通道接收方法调用的XML表示,识别有问题的方法并重建序列化的参数序列。通过一个简单的分派器,它调用适当的组件方法。就像存根传递参数一样,它随后通过网络传递返回值重新构造参数序列需要基本类型、组件对象和辅助对象的解析器至 于 序 列 化 器 , 前 两 个 是 相 当 简 单 的 构 造 。 对 于 辅 助 对 象 ,XMLSerializer 和 XMLSerializer 之 间 以 及 XMLSerializerStream 和XMLSerializerStream之间存在直接对应关系。主要的区别是,静态解析器不能使用多态调用。他们必须明确调度已知的子类型名称,以调用构造函数,这些构造函数被写入辅助类。4执行为了将上一节中讨论的架构元素添加到第2节的组件和辅助类中,我们使用了由Apache系统提供的按照惯例,元图可以被分解成单独的分析和转换阶段。前者从现有来源获得所需信息,后者执行所需的实际修改。在下面的小节中,我们将分别讨论这些阶段。洛维和诺加1134.1分析分析阶段遍历输入程序并导出转换阶段所需的数据。它主要计算组件的集合和对组件的方法调用所需的辅助类型的集合。然后,它确定成员变量名称和辅助类型的类型,以及基本子类型关系及其传递闭包。组件存根和骨架生成还需要有关可用方法的信息。虽然实际的实现略有不同,但分析可以用固定点迭代来表示。它的初始化看起来像这样:• 标识继承Component的所有接口。• 对于每个这样的接口,确定所有可用的方法。• 对于每个这样的方法,将其签名中的所有类型添加到使用的类型集中。• 将辅助类型设置为空集。单个迭代步骤由以下操作组成• 对于所有使用的数组,将它们的基类型添加到使用的类型中。• 将所有未继承Component的已使用类型添加到辅助类型。• 对于所有辅助类型,确定它们的超类和超接口。• 将它们添加到已使用的类型中。• 对于所有辅助类型,确定所有子类型。• 对于所有辅助类型,标识其成员变量。• 对于所有这样的成员变量,将它们的类型添加到使用的类型中。显然,需要输入程序的语义丰富的模型来执行这些计算。虽然没有必要访问方法bod-也就是说,类型关系、成员签名和成员变量的完整语义分析是这种定点迭代的先决条件4.2转型转换阶段作用于程序模型,以实际合并所需的修改。在这种情况下,没有更改或删除-只执行添加。尽管显然有必要组合各种方法,例如,静态序列化器和序列化帮助器,这并不影响现有的方法体。事实上,存根、骨架、静态序列化器和并行化器类可以组装成一个整体并添加到模型中。类似地,所有序列化和非序列化帮助器都可以单独组装并添加到方法级别的模型中。洛维和诺加1144.3结果我们用Bullder实现了分析和转换阶段。由于上面提到的操作与编译器方法非常接近,我们在这里不提供实际的元程序代码。有关技术细节,请参阅安装我们的工作原型支持完整的Java类型系统,包括所有原始类型,数组和任意用户定义的类,抽象类和接口。序列化器、重复序列化器、存根和骨架都正确生成。远程调用是可操作的。当然,一个工作原型不是一个经过时间考验的产品。我们不处理例外情况。Object仍然存在问题,因为它同时具有组件和辅助子类。我们不能处理二进制类-虽然理论上很简单,但到用户定义的外部序列化器的映射尚未实现。 同样,我们的网络处理非常基础,缺乏可扩展的组件寻址方案或安全处理。然而,这些域问题与元编程示例的关系不大重要的是:虽然我们之前接触到的是严格的理论,但我们能够在四个人天内建立一个工作原型。生成代码的元程序和运行时框架加在一起达到2500字节。5结论本案例研究得出三个不同层次的结论:域,过程和系统架构。让我们首先考虑问题域。我们已经成功地实现了Web服务。我们的元程序侵入性地将现有组件集成到Web调用架构中。虽然我们选择实现简单的XML编码以提高可读性,但是使用元编程技术可以轻松实现与SOAP和WSDL的完全一致性显然,元编程在这个领域工作得很好。正如我们在解决方案的组成部分中所遇到的那样,序列化的相关领域以及数据绑定和持久化的更大问题也非常适合元编程方法。这个例子的软件开发过程对我们来说是一个惊喜。虽然我们之前没有使用过Quadder,但元程序和相关的运行时框架在四个人天内就实现了。加在一起,它们总共只有2500磅。这是对元编程表达能力的有力证明。在架构领域,我们注意到元编程系统是一个很好的抽象层封装一些82000背后的一个干净的接口,封装器提供了一个完整的结构树与完整的语义分析和支持一般的转换。这是一个更难的问题洛维和诺加115元编程系统元程序(侵入式适配器)元程序(侵入式适配器)元程序(侵入式适配器)Aspect Weaver比大多数可以想象的个体转化都要多。元编程系统使复杂的编译器技术变得容易访问。因此,它们是大型系统的有用构建块。阅读操纵软件的大型系统时,人们不能不注意到元编程、侵入式适应和面向方面编程领域的术语是重叠的。根据我们的经验,我们建议此类系统采用分层架构(见图4)。图四、元程序设计系统的高级体系结构一个元编程系统,如Adjudder,是基础。个人的侵入性适应,如我们在XML Web服务中的研究,是建立在这一层上的元程序。最后,一个方面编织者在上面协调各种侵入性适应的应用。前面的路是什么?我们计划进行进一步的个案研究。这增加了元程序库,用于在上面概述的体系结构中进行侵入性调整。在适当的时候,这种策略应该会产生关于元程序设计的有价值的见解。它将为可互操作的元图铺平道路,可能有一天会由方面编织者编排,这仍然是未来研究的主题。引用[1] 首页关于PURE机械手http://ivs.cs.uni-magdeburg.de/~puma/home-eng.html网站,2 0 0 1 年[2] 变形。 http://transmogrify.sourceforge.net,2001年。[3] IRA D.巴克斯特转换系统:面向领域的组件和实现知识重用。1999年,第九届软件重用制度化研讨会[4] R. 菲尔丁,J。Gettys,J.Mogul,H.弗里斯蒂克湖Masinter,P.Leach,以及T.伯纳斯-李 超文本传输协议 IETF RFC 2616,http://www.ietf.org/rfc/rfc2616.txt。[5] 詹姆斯·高斯林比尔·乔伊和盖伊·斯蒂尔JavaTM语言规范。Addison-Wesley,第2版,1996年。洛维和诺加116[6] 安德烈亚斯·路德维希。Recorder Homepage. http://recoder.sf.net,2001年。[7] 约翰·麦卡锡Lisp 1.5. ACM通讯,3(4),1960年。[8] Corba 2.4.2规范。天啊,http://www.omg.org/technology/documents/formal/corbaiiop.htm。[9] Enterprise JavaBeans 1.1规范。SUN微系统公司,http://java.sun.com/products/ejb/docs.html。[10] JavaBea(tm)1.0.1规范。 SUN微系统公司,http://java.sun.com/products/javabeans/docs/spec.html网站,一 九 九七 年。[11] 简单对象访问协议(SOAP)1.1. W3C Note 08 May 2000,http://www.w3.org/TR/2000/NOTE-SOAP-20000508网站,两 千[12] Web服务描述语言(WSDL)1.1. W3C Note 2001年3月15日,http://www.w3.org/TR/2001/NOTE-wsdl-20010315,2001年。[13] 可扩展标记语言(XML)1.0. W3C推荐,http://www.w3.org/TR/1998/REC-xml-19980210,1998年。[14] XML架构第1部分:结构。 W3C建议2001年5月2日,http://www.w3.org/TR/2001/REC-xmlschema-1-20010502网站,2001年[15] XML架构第2部分:数据库。 W3C建议2001年5月2日,http://www.w3.org/TR/2001/REC-xmlschema-2-220010502网站,2001年
下载后可阅读完整内容,剩余1页未读,立即下载
cpongm
- 粉丝: 5
- 资源: 2万+
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- Java集合ArrayList实现字符串管理及效果展示
- 实现2D3D相机拾取射线的关键技术
- LiveLy-公寓管理门户:创新体验与技术实现
- 易语言打造的快捷禁止程序运行小工具
- Microgateway核心:实现配置和插件的主端口转发
- 掌握Java基本操作:增删查改入门代码详解
- Apache Tomcat 7.0.109 Windows版下载指南
- Qt实现文件系统浏览器界面设计与功能开发
- ReactJS新手实验:搭建与运行教程
- 探索生成艺术:几个月创意Processing实验
- Django框架下Cisco IOx平台实战开发案例源码解析
- 在Linux环境下配置Java版VTK开发环境
- 29街网上城市公司网站系统v1.0:企业建站全面解决方案
- WordPress CMB2插件的Suggest字段类型使用教程
- TCP协议实现的Java桌面聊天客户端应用
- ANR-WatchDog: 检测Android应用无响应并报告异常
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功