用于静态键入的基于类的面向对象的软件的非阻挡动态更新的方法、计算机程序产品和系统的制作方法

文档序号:6351869阅读:203来源:国知局
专利名称:用于静态键入的基于类的面向对象的软件的非阻挡动态更新的方法、计算机程序产品和系统的制作方法
技术领域
本发明涉及在不需要重新启动或导致软件的运行时间状态丢失的情况下将在计算机系统上活动运行的软件的编程代码从其当前的版本动态更新为新的版本。更特别地,本发明涉及使得能够动态更新以静态键入的基于类的面向对象的编程语言书写的活动运行的软件的状态和功能,其中,如由以Java 编程语言中书写的软件体现的那样,语言的编辑器以在虚拟机上动态加载和执行的基于字节代码的类定义的形式产生可执行的对象代码。通过本发明,活动运行的软件系统不必再在对于软件的编程代码的变化生效之前通过标准的中止、重新调配和重新开始方案,原因是这些变化作为动态更新过程的结果立即生效。
背景技术
对于许多重要的应用,存在在非常可靠的计算机系统上运行的高可用性计算机应用。这些系统和程序一般I天运行24小时,I周运行7天,并且,处理的任何中断会在顾客服务上并且在一些情况下在安全上具有严重的后果。例如,因特网和万维网上的电子商务的出现要求电子商务站点一直可用于处理交易。其它的例子包括信用卡交易处理应用、空中交通控制应用等。由于用于这种任务关键应用的软件在开发环境上“离线”增强,因此,变得必须将这种增强的软件“在线”展开或刷新到产生环境中。以前的展开这种增强的方法要求保存状态数据、关断或另外削弱关键应用的可用性、安装新的软件、重新开始应用或另外使得其完全可用并然后恢复软件的以前状态。在这一点上,应用会用现有的数据运行增强的代码。通过关断系统或诸如手动停止系统的其它的性能削弱事件,服务被打断。为了避免服务打断,软件更新常常尽可能地被延迟,从而存在危及安全性和防护性的风险。因此,需要在不需要关断或中断该系统的情况下向活动运行的系统内的软件的一个或更多个模块施加变化(增强和/或维护)。并且,需要在活动运行的系统内添加或删除这种模块。由于以静态键入的基于类的面向对象的编程语言书写任务关键应用的成长的类,因此,需要在这种应用的各单个模块内解决动态更新类的特定的挑战。当更新以静态键入的基于类的面向对象的编程语言书写的模块时,在运行的系统上,更新会需要保存来自变化的类的先前的实例的状态信息并将该信息提供给这些类的新的实例。并且,需要确保以极微细的方式完成一组类的更新,原因是,由于类的前面版本和新的版本的类型的变化,因此它可另外导致二进制不兼容,这将导致运行时间失败并使整个系统停止。通过Dmitriev提出的类重新加载设施的实现[5],广泛接受的静态键入的基于类的面向对象的编程语言Java 不具有一些用于类的动态重新定义的支持。重新定义可改变方法主体的编程代码、常数存储库和属性。但是,类重新定义必须不添加、去除或重新命名域或方法、改变方法的签名、改变变址数或改变继承分层。提出这些限制以避免类的随后的版本之间的二进制不兼容问题。实际上,这些限制使得Java 中的当前的类重新定义能力不适于支持大的长龄的任务关键应用所需要的大多数的动态更新。在[6]中,Malabarba等公开了基于具有新的动态类加载器的修改的Java虚拟机的方法Dynamic Java Classes,在该方法中,只要当前存在于活动行动的软件中的其它类都不依赖于改变的类的一部分,就允许Java类的任何变化。通过在更新的类上施加该限制,该方法变得动态键入安全。例如,如果没有其它的类依赖于域或方法,那么它可被去除。类似地,只要对于类的类型的变化不导致与类的从属物的类型违反,就可提出这些变化。由于他们的新的动态类加载器不支持导致类型违反的类的传递加载,因此,他们的方法限于一次动态加载单个类,这是要限制任何非琐碎软件更新的变化范围。并且,他们的方法在更新多线程应用中的类时必须阻挡任何活动的线程以防止出现紊乱条件。当出现软件更新时,线程的这种阻挡导致应用执行中的不希望的冲撞。在[7]中,Subramanian等公开了基于修改的Java虚拟机、允许开发人员在类层
次结构内的任何位置上添加、删除和替代域和方法的方法JVOLVE。JVOLVE通过添加和协调VM类加载、及时编辑、调度、返回载体、栈上替代和废料收集实现这些更新。为了初始化新的域并更新现有的那些,JVOLVE应用类和对象变换器功能,前者用于静态域,后者用于对象实例域。通过检查前者与更新类的新版本之间的差异的所谓的Update Preparation Tool对于各更新准备类和对象变换器功能。JVOLVE在MV安全点上停止执行线程,在该MV安全点上,执行废料收集(GC)和线程调度是安全的。JVOLVE利用废料收集器和JIT编辑器以更新与改变的类相关的代码和数据。JVOLVE初始化全堆放GC以找到更新的类的现有对象实例,并且通过使用提供的对象变换器初始化新的版本。JVOLVE使现有的编辑的代码无效并且对于所有改变的方法实现安装新的字节代码。当应用重新开始执行时,当它们被下一次调用时,这些方法被JIT编辑。JVolve要求软件到达静止的状态,即,在可出现更新之前,所有的应用线程必须在VM安全点上停止。更新处理使用要求应用对于全堆放废料收集暂停的停止世界的基于废料收集的方法。MV安全点上的应用线程的该同步化的阻挡导致在不可预测的时间周期上打断服务。在[8]中,Gustavson公开了在程序运行的同时扩展具有更新类的能力的Java虚拟机的方法JDrums。为了在运行的程序中用预先存在的实例更新类,JDrums根据更新规范将所有这种对象转换成新类的对象。更新规范必须一起具有当开始更新时被更新的类。类似地,能够对于更新的类中的静止数据规定更新规范。在按照更新类的所谓的CONVERSIONCLASS中,更新规范在Java源代码中被限定。转换类包含限定如何实施转换的方法。JDrums不支持动态改变类的继承分层。在[3]中,Orso等公开了通过对象交换器基于间接的热交换技术、允许从运行的Java应用替代、添加和去除类的方法DUSC (通过类的交换的动态更新)。DUSC使得能够通过首先施加类重命名和代码重写以引入对象交换器并然后通过在运行时间上交换类执行类更新实现动态更新。该方法对于应用编程施加大量的限制不允许应用中的类直接访问更新类的公共或保护的域;反射不被应用于任何更新类或更新类的任何成分(作为反射的形式,也包含检查关于特定的类的信息的任何方法,诸如java. lang. Class中的方法);更新类的新的版本提供由类的先前版本提供的相同的界面;更新的类不包含本机方法;没有更新类的方法在更新中执行(即,没有类的方法处于栈上。)当通过使用DUSC动态地编程可更新的应用时,开发人员必须考虑所有这些限制。在[9]中,Bialek等公开了基于分割Java应用以在可更新的单元中进行这些分割的方法。应用的分割封装他们包含的类,并使得提供和需要的界面变得明显,从而使得它们与成分类似。如果不是更新被拒绝,那么新分割的实现的提供的界面必须至少包含先前的版本的提供的界面。由此,方法不支持从提供的界面去除公共成员。可由开发人员提供或者从源代码自动地提取关于分割的信息。公开的方法允许通过使用版本适配器添加方法、域和构建器并改变方法签名。各分割提供状态迁移功能。用于分割的状态迁移功能包含旧的分割的对象的状态向它们的相应的新的版本的映射。应用编程人员需要写入这些版本适配器和状态迁移功能。当分割被更新时,所有对于分割的访问被阻挡。在完成更新之后,分割被解锁,并且,应用可通过使用更新的分割的对象的新的版本继续其正常的执行。在[10]中,Hjalmtysson和Gray公开了在类级别上允许执行C++程序的运行时间更新的方法Dynamic C++类。方法针对这样一种问题,即,C++不直接支持动态可加载模块的产生,这使得难以跨着动态链接界面保存程序级提取。Dynamic C++Classes基于开发 通常的C++特征的代理方法,并可与最新式的编辑器一起被编辑。代理方法支持现有的类的版本更新以及新的类的引入。为此,主程序必须能够与新的实现通信(调用其方法)。因此,各实现必须在编辑时间具有主程序已知的界面。各新实现更新现有的类(新版本)或引入使用已知的界面的新类(新类型)。由于该限制,因此,方法仅限于方法的更新。在[11]中,Stanek等公开了允许动态更新C++类的方法Dynamic EvolvableC++Classes0包含添加、去除、更新、合并和分离类。通过使用状态变换功能启用类的动态合并和分离。对于与Dynamic Evolvable C++Classes 一起的应用,需要应用的一些准备。准备包括(a)通过使用由Dynamic Evolvable C++Classes的下层构架提供的智能指示器和容器模板写入应用;(b)对于各类实现由构架限定的共同的API ; (C)实现用于实例产生和破坏的工厂方法;(d)将各类编辑到单独的动态链接的库中;和&)用构架的类登记登记动态类库中的每一个。下层的构架基于实现为C++模板的智能指示器,以在更新的状态变换之后保持对象基准的跟踪。如给出的那样,由于多线程应用中的紊乱条件下的安全状态变换被忽略,因此方法仅适用于单个线程应用。在[12]中,Chen等公开了允许通过并行地运行旧的和新的版本动态地更新多线程软件的方法POLUS。POLUS通过同时允许应用数据的旧版本和新版本的共存实现并行执行,并且,不管什么时候存在对于要更新的数据的版本的写入访问,都通过呼叫一些状态同步功能保持版本之间的连贯性=POLUS通过使用由操作系统提供的调试API在更新过程中写保护数据的版本(例如,Unix中的ptrace和Windows中的DebugActiveProcess)。当几个线程同步访问多线程软件中的数据的不同的版本时,该同步化方法确保连贯性。一旦在旧的版本中不存在活动线程,并行的执行就终止。从此时起,所有的功能呼叫通过使用二进制重写从旧的版本被重新引向新的版本,以在原功能的序言中插入重新引导跳动指令。与C编程语言类似,POLUS是用于必要的(过程的)编程语言的动态更新的设计。POLUS因此不适于基于类的面向对象的编程语言。US7530077公开了用于通过使用外部源在要动态更新的用户应用的数据空间内启用可变数据的最小单位的方法和服务。通过使得能够对于代理题目选择和链接数据单位的动态更新功用(DUU)增强应用GUI。本发明针对在不损失活动状态的情况下动态更新活动运行的软件的编程代码,而US7530077的方法针对动态更新数据值,是不同的问题。US6629315公开了用于在活动运行的计算机系统内动态刷新软件模块的方法、计算机程序产品和系统。现有的模块或多个模块(可执行代码的可识别的单元)准备好在活动计算机系统中执行。出于更新现有的模块的目的,在功能上与现有的模块对应的新的模块被加载到计算机系统存储器中。准备新的模块以通过指向当前被现有模块使用的相应的状态数据执行,并且另外使其准备好接管执行。为了从现有模块到新模块切换从呼叫点或呼叫基准的访问,在专门处于刷新过程相对短暂时刻的执行上保持锁定。现在释放锁定,从而允许通过现有数据执行新模块由此实现模块的更新或刷新。最后,从存储器去除先前或“旧”模块。本发明使得能够非阻挡地动态更新以静态键入的基于类的面向对象的编程语言书写的活动运行的软件,而US6629315的方法限于阻挡 以过程语言书写的软件的动态更新。鉴于以上的情况,需要在不需要重新开始软件或运行软件的计算机的情况下并且在不作为在其上面执行更新的结果损失软件的运行时间状态下透明地非阻挡地动态更新静态键入的基于类的面向对象的软件的系统、方法和程序产品。

发明内容
本发明的实施例提供用于被编辑为字节代码并在活动运行的桌面、服务器、主机或嵌入的计算装置上的平台独立虚拟机中执行的静态键入的基于类的面向对象的软件的非阻挡动态更新的系统、方法和程序产品。特别地,根据本发明,为了避免重新开始启动软件以使得软件的编程代码的版本之间的改变生效的需要,用于软件的类定义的不同的版本的字节代码在被加载到虚拟机中时经受一系列的变换。这些变换允许存在于活动运行的计算机系统中的类的先前的版本的所有活动对象的运行时间切换到用于在从类的先前版本例示对象之后动态加载类的新的版本的相应的对象的代理对象;其中,在对象和类的代理与它们的共存的版本之间共享对象身份和类分配。本发明通过首先执行虚拟机特定自举类的预引导字节代码变换动作,以通过将字节代码注入到自举类中使得对于更新的自举类的前面的版本的已例示的对象实现由更新的子类限定的扩展和/或推翻行为,对于自举类的应用子类的将来更新准备自举类。然后,本发明通过执行变换的自举类构成用于应用实例的新的一组虚拟机自举类的应用实例前进。在执行中,本发明截取加载到虚拟机中的每个类的字节代码的加载,并且一旦类加载被启用,本发明就在连续的阶段中变换类的字节代码以启用用于对接共存对象和类的共享的对象身份和类类型身份。根据加载的类的类别,本发明执行不同的变换系统类的字节代码被变换,以对于从它们导出的应用子类的将来的更新准备系统类,通过将字节代码注入到系统类中使得对于更新的子类的前面的版本的已例示的对象实现由更新的子类限定的扩展和/或推翻行为实现这一点;应用类的字节代码被变换,以通过将字节代码注入到应用类中使得应用类更新可用,由此启用应用类及其实例的运行时间切换,以对于以非阻挡方式自动传送身份和状态的将来的相应的对象和类变为代理类和对象。最后,在软件更新包含用于构成当前运行的系统和新的版本之间的不同的类定义的改变组的字节代码的软件更新的情况下,本发明通过透明地切换从改变组中的类例示的当前活动对象的行为以变为新类定义的将来的即需的例示的相应的对象的未初始化的代理,执行活动运行的计算机系统的非阻挡软件更新。
在本发明的变更例中,其中,在对于类的晚时的版本的对象的新的相应的版本的动态软件更新之后,活动对象的对象身份和状态在第一用途上成对,变换字节代码包含首先构建更新的类版本的新的未初始化的对接对象,然后构建相应的对象的唯一身份ID,从而确保对象的将来的增强的身份检查不管它们的特定的版本如何都对于相应的对象产生成立;并且,最后,在类更新之后,从第一用途上的对象的前面的相应的版本迁移状态。在另一变更例中,变换字节代码将自动产生的字节代码方法插入初始化对于代理对象为新的状态的触发未初始化的对接对象的构建的部分的应用类中。在另一变更例中,变换字节代码通过以下的过程确保代表同一类的不同的版本的多个类可共存通过单独的类加载器加载更新的类,由此,代表相同的类的多个类型被加载到虚拟机中;并且,通过执行由共享相同的类型名称空间的相应的版本替代动态类检查动作的操作数的动态类类型检查的字节代码,替代执行由语言限定的动态类类型动作的类中的字节代码。在另一变更例中,变换字节代码确保方法呼叫的转送将对象变换成将对于其成员的所有访问转送到相同的类的新版本的新的相应的对象的代理中。通过首先变换类的字节代码使得参照多个相应的对象中的任一个的客户机将总是看到具有可从其自身的类加载器的可到达类型分配的类型的对象实现这一点。这包括通过对于符合“instanceof”指令的右手侧操作数的类型名称空间的特定相应对象表现执行“instanceof”检查的字节代码,替代虚拟机字节代码指令“ instanceof”,然后,通过对于符合“CHECKCAST”指令的右手侧操作数的类型名称空间的特定相应对象表现执行“CHECKCAST”检查的字节代码,替代“CHECKCAST”的虚拟机字节代码指令等同;最后,将类和类的先前加载的版本的对象的对象运行时间切换成将任何将来请求重新引导到相应的相应的新类和对象的代理,其中,从新的相应的表现获得的可能的值由符合代理成员的呼叫方的类型名称空间的代理表现替代,并且,插入的用于控制重新引导处理的字节代码通过符合重新引导处理的接收器的类型名称空间的相应的表现替代由代理成员的呼叫方给出的参数。在另一变更例中,变换字节代码通过从代理对象到相应的新的对象的方法呼叫的虚拟机表现的高速缓存确保有效的转送。在另一变更例中,通过由通过使用属于相同的类名称空间的相应的对象版本执行身份检查的字节代码替代用于比较对象的身份的虚拟机字节代码指令,字节代码变换使得能够在相同的类的不同的版本的活动对象之间共享对象身份。在另一变更例中,通过在一个按照宣告的域产生的得到方法和一个按照宣告的域产生的设定方法中在包裹域访问的应用类中产生字节代码,状态在从相同的类的不同的版本例示的多个相应的对象之间被共享。由此,保持记录代表相同的对象的一组相应的对象中的哪个对象版本保持当前的单个共享的域值。得到的方法确保当在代理对象上被调用时域将请求转送到代理对象的最近的相应的版本,其中,从最近的相应的获得的域值被转换成代理对象的类名称空间的域值,这确保如果当前不在最新的相应的对象中存在域值那么在相应的对象中搜索域值并通过首先将其转换成最新的相应的对象的类型名称空间传送它,这样做确保如果在最新的相应的对象中存在域值那么读取域值并且如果不存在平均时间的更新那么返回它;即,如果在读取域值之后出现宣告产生域得到方法的类的更新那么它将读取请求转送到代理对象的最新的相应的版本,其中,从最新的相应的对象获得的域、值被转换成当前代理对象的类型空间的域值。类似地,插入设定方法中的算法确保,当在代理对象上被调用时域将请求向前写入到代理对象的最新的相应的版本,其中,向最新的相应的对象转送的域值被转换成最近的相应的对象的类型名称空间的域值;由此确保,如果当前不在最新的相应的对象中存在域值那么写入域值并且找到事先保持域值的相应的对象并且请求其清除先 前的状态。这确保,如果在最新的相应的对象中存在域值并且如果不存在平均时间的更新那么写入域值;以及,如果在写入域值之后出现宣告产生域得到方法的类的更新那么它将读取请求转送到代理对象的最新的相应的版本,其中,转送到最新的相应的对象的域值被转换成最新的相应的对象的类型名称空间的域值。在另一变更例中,变换字节代码确保在由相应的对象共享的暂时锁定机制下执行从先前的版本向最新的相应的对象的状态的迁移。在另一变更例中,变换字节代码确保在由相应的对象共享的暂时锁定机制下执行先前对接版本中的状态的清除。在另一变更例中,变换字节代码通过使用共同同步对象对于对象及其代理对象的组确保对于线程的同步化访问。变换字节代码包括两个步骤通过在方法的开始插入MONITORENTER等同指令并在方法的每个离开点上插入MONITOREXIT等同指令的字节代码,替代内置的同步化访问修改器,其中,同步化的对象对于相应的对象和类是相同的;和通过通过对于相应的对象相同的唯一可识别对象交换同步化的对象的字节代码,替代执行由语言限定的同步化的动作。在另一变更例中,变换字节代码包括在应用类中在各方法的开始插入字节代码,从而确保代理对象自动地使转送适于从可用的类的最新的版本例示的相应的对象。在另一变更例中,变换字节代码确保通过在运行时间替代方法体的定义转送对于对象的访问。在另一变更例中,变换字节代码确保活动对象在切换中在不阻挡当前执行对象内的代码的任何线程的情况下被动态切换成代理对象。在另一变更例中,变换字节代码确保代理对象与从类的最新的版本例示的即需的构建的对接对象共享状态和身份。在另一变更例中,变换字节代码确保代理对象与从类的最新的版本例示的即需的构建的对接对象共享状态。在另一变更例中,变换字节代码确保代理对象与从类的最新的版本例示的即需的构建的对接对象共享身份。在另一变更例中,变换字节代码确保代理对象的客户机对于代理对象的类的类型保持一个或更多个参照,但是通过代理成员向可用的最新的对接类版本的转送使用类的最新版本的方法体。在另一变更例中,变换字节代码包含直接通过调用宣告类中的相关的产生的得到方法的字节代码替代读取对象状态的所有反射机构。在另一变更例中,变换字节代码包含直接通过调用宣告类中的相关的产生的得到方法的字节代码替代写入对象状态的所有反射机构。在另一变更例中,变换字节代码包含在类初始化方法的开始插入字节代码,以确保类初始化方法中的原始代码在类的前面版本已先前被加载到虚拟机中的情况下不被执行。在另一变更例中,变换字节代码包含如果在宣告构建器的子类的代理实例上出现构建,那么在对象构建器的开始插入字节代码,以确保构建器即不执行原始代码也不将构建器调用重新引导到类的最新版本的相应的对象。在另一变更例中,变换字节代码包含如果在代理实例上出现终化,那么在对象终化器的开始插入字节代码,以确保终化器即不执行原始代码也不将终化调用重新引导到最新的相应的对象。在另一变更例中,变换字节代码包含通过确保产生的克隆包含与由被克隆的对象的所有相应的对象共享状态等同的状态的字节代码,替代由语言限定的克隆的出现。 在另一变更例中,变换字节代码包含通过最近的相应的对象替代串行化的对象的字节代码,替代对象串行化的出现,其中,插入的字节代码确保共享的对象状态在继续串行化过程之前被传送到最近的相应的对象。 在另一变更例中,变换字节代码包含,通过以下的过程通过将访问请求重新引导到最近的相应的阵列对象替代访问阵列的指令首先将由替代的阵列读取动作获得的值转换成呼叫方类的类型名称空间的值;并然后将要在替代的阵列写入动作中使用的值转换成最近的相应的阵列对象类型名称空间的值。在另一变更例中,变换字节代码允许被动态加载的类的新版本的类型信息表示与类的先前的加载的版本不同的继承分层。在另一变更例中,变换字节代码允许被动态加载的类的新版本的类型信息表示与类的先前的加载的版本不同的界面。在另一变更例中,变换字节代码允许被动态加载的类的新版本中的方法宣告与类的先前的加载的版本不同。在另一变更例中,变换字节代码允许被动态加载的类的新版本中的域宣告与类的先前的加载的版本不同。参照以下的附图和详细的描述,本领域技术人员很容易理解根据实施例的其它的方法、系统和/或计算机程序产品。所有这些附加的方法、计算机程序产品和/或系统要包括于说明书内,要处于本发明的范围内并且由所附的权利要求保护。


以上简要描述的本发明的更详细的说明将通过参照在附图中示出的其特定的实施例被呈现。这些附图仅示出本发明的一个或更多个典型的实施例,因此不被视为其范围的限制。参照以下的附图,在整个附图中,类似的附图标记表示相同的要素。图I是可实施本发明的可以为桌面、工作站、服务器、主机计算机、嵌入计算装置等的一般计算装置的框图。图2表示系统中的模块根据它们的从属物被链接的示例性的系统快照。图3表不In-Place Proxification技术的概念概览。图4表示包含的部件成功更新之后的模块连接的例子。图5表示为了与更新的模块从属物链接执行客户机的动态更新之后的模块连接的例子。
图6是表示为了实施本发明的自举相采取的高级步骤的流程。图7是表示为了实施计算机程序中的活动运行的模块的动态更新采取的高级步骤的流程。图8是表示为了在类的字节代码被加载到虚拟机之前变换这些字节代码采取的高级步骤的流程。图9. I 9. 31是表示在本发明的实现中在类上完成的详细的字节代码变换的流程以及修改的字节代码在使用本发明的系统的执行中如何表现。
具体实施例方式如上所述,本发明提供用于在活动运行的桌面、服务器、主机或 嵌入的计算装置上的虚拟机中执行的静态键入的基于类的面向对象的软件的非阻挡动态更新的系统、方法和程序产品。特别地,本发明通过在使得它们能够被动态更新的类定义的字节代码上执行变换,提供动态更新。类的更新在模块的颗粒水平上生效。不破坏与先前的运行的版本的模块AP兼容性的变化没有超出模块自身的影响。违反二进制兼容性的那些[2]扩展更新组以还包含用于所有的运行的依赖物的新的API可兼容模块版本。更新中的变化可包含改变方法体、添加/去除方法、添加/去除构建物、添加/去除域、添加/去除类、改变界面、替代超类、添加/去除实现的界面和透明的对象状态迁移,同时确保更新类定义的类型安全性及其在运行的软件的不同的版本中的共存的依赖物。一般地,方法支持类的水平上的代码和状态的预期不到的动态软件发展。基于用于API发展的一般接受的指导,本发明的方法允许从在中止系统之前将状态串行化并在重新开始重新部署系统之后去串行化的方案导出的相同的一组状态完全更新。如这里使用的那样,术语“模块”或“软件模块”意味着可从长程存储介质(诸如但不限于盘驱动、CD-ROM、带等)独立加载的一条计算机代码。在本发明的上下文中,“模块”意味着字节代码表现和补充的应用资源的形式的类定义的可识别的集合。并且,模块将具有外部世界即独立的模块可以到达其公共成员的很好地限定的API。模块明确地宣告对于其它的部件的依赖性。如这里使用的那样,术语“改变组”意味着为了避免二进制不相容必须一起被微细地重新定义的一组类定义。如这里使用的那样,术语“类型名称空间”意味着,来自特定的上下文的可到达的类型是对象、类或模块中的一个。可到达的类型由可直接从给出的上下文内加载的类型给出。图I是可实施本发明的诸如工作站的计算装置的框图。图I的环境包括包含相关的外设装置的诸如个人计算机、工作站、企业主机计算机、服务器、膝上型计算机、手持计算机、信息器具等的单个代表性的计算装置100。计算装置110包含微处理器102或等同的处理能力和根据已知的技术连接并启用微处理器102和计算装置100的部件之间的通信的总线104。注意,在一些计算装置中,可存在加入其中的多个处理器。微处理器102通过总线104与存储器106通信。诸如随机存取存储器(RAM)、只读存储器(ROM)、快擦写存储器等的存储器108可直接被访问,而诸如硬盘的二次存储装置110和诸如软盘驱动、⑶ROM驱动、带存储器等的可去除存储装置112可通过添加的接口硬件和软件被访问,这在本领域中是已知和惯常的。可去除的存储装置112将具有与其相关的将保持计算机可用数据并为计算机可用介质的形式的诸如磁盘、CD、带卷或盒子、固态存储器等的适当的类型的可去除的介质114。注意,计算装置100可具有多个存储器(例如,RAM和ROM)、二次存储装置和可去除存储装置(例如,软盘驱动和⑶ROM驱动)。计算装置100 —般包括通过总线106连接微处理器102与诸如键盘118、鼠标或其它的指示装置120、显示器122 (诸如CRT监视器、IXD屏幕等)、打印机124或诸如触摸敏感屏、数字化的键入盘等的任何其它的用户接口装置的一个或更多个接口装置的用户接口适配器116。注意,为了实现与用户接口装置的必要的连接,计算装置100可使用多个用户接口适配器。计算装置100还可通过诸如电话、电缆、无线调制解调器、ISDN适配器、DSL适配器、局部区域网络(LAN)适配器或其它的通信信道的通信适配器126与其它的计算装置、计 算机、工作站等或它们的网络通信。这给出对于网络128(LAN、广域网络(WAN)、因特网等)、可用于访问其它的网络或计算机的电话线130、诸如蜂窝式电话网络的无线网络132和其它的通信机构的计算装置直接访问。注意,计算装置100可使用用于进行必要的通信连接的多个通信适配器(例如,电话调制解调器卡和Cellular Digital Packet Data (CDF1D)X计算装置100可与LAN或WAN中的其它计算装置相关,或者,计算装置可以是具有另一计算机等的客户机/服务器配置中的客户机或服务器。所有这些配置以及适当的通信硬件和软件在本领域中是已知的。计算装置100提供诸如操作系统软件134、中间件软件136和应用软件138的用于运行软件的设施。注意,这种软件执行任务,并且可与该计算装置和其它的计算装置上的各种软件部件通信。本领域技术人员可以理解,诸如这里描述的计算机程序(包括操作系统软件134、中间件软件136和/或应用软件138) —般分布为具有计算机可用介质或包含或存储程序代码的介质的计算机程序产品的一部分。因此,这里使用的“介质”、“媒介”、“计算机可用介质”或“计算机可用介质”可包含计算机存储器(RAM和/或ROM)、磁盘、带、紧致盘、集成电路、可编程逻辑阵列(PLA)、通信电路上远程传送、诸如蜂窝网络的无线网络上的远程传送或具有或没有适当的适配器接口的可由计算机使用的任何其它介质。注意,计算机可用介质的例子包括但不限于诸如CD Rom、磁盘和硬驱动等的可触知的物理介质以及程序被电子分布时的诸如有线或无线的载波信号的其它不可触知的物理介质。还应注意,可从 Mountain View, Calif.的 Sun Microsystems 得到的根据 JAVA 技术的 “servlets” 或“applets”应被视为计算机程序产品。虽然启用的指令会被“写入于”磁盘或带上、“存储于”集成电路或PLA中、“承载于”通信电路或无线网络上,但是,应当理解,出于这里描述的本发明的目的,计算机可用介质将被称为“承载”指令,或者,指令(或软件)将被称为处于介质“上”。因此,“体现于”介质“上”的软件或指令意图在于包含以上和所有的指令或软件可与计算机可用介质相关的等同方式。为了简化,使用术语“计算机程序产品”以表示以上限定的承载或具有体现于其上面的任何形式的软件或指令以使得计算机系统(或多个操作系统)能够根据以上识别的本发明动作的计算机可用介质。
类似地,应当理解,上面实现本发明的计算机硬件包含基本上独立地一起动作或者分布于网络上的一个或更多个处理器,并且还包括用于存储执行本发明所需要的指令和计算的存储器。本领域技术人员可以理解,可以以在本领域中已知的各种不同的方式产生根据本发明的系统。例如,图I所述的一般用途计算装置可配有适当的软件,使得计算装置如以下描述的那样起作用。并且,可以使用离散的电子部件以产生实现全部或一部分的功能的系统。最后,注意,可以以类似的方式使用多个运行适当的软件的计算装置或离散的电子部件的组合。基本上,硬件被配置(通过软件、顾客设计等)以执行构成本发明的功能要素。参照图2,该图表示由大量的部件206构建的示例性的系统设置。首先,如202所示,系统在时间t=0上表示系统内的部件的典型的连接,从而反映208中的类可使用206中的类的事实。在运行时间上,通过运行系统中的类加载器保持这些连接。本发明基于由虚拟机执行的当代编程语言中的典型的类加载器设置的知识。一般地,每个模块被分配给单独地负责加载明确由该模块宣告的类和资源的明显的类加载器。在模块从属204中宣告的 类的类加载包含找到相关的类加载器并代表对于该类加载器的类加载。该广泛应用的方案导致各类的唯一的表现,这直接在不同的模块进行类型共享。但是,在由模块限定的类的动态替代的背景下,出现问题模块如何到达在它们的模块从属的更新的版本中宣告的类?在缺少对于类重新加载的内置支持的情况下,新的类加载器必须被分配各替代的成分212。从虚拟机的观点,由此产生新的一组的明显的类型。现在参照图210,由于客户机模块与更新的模块的前面版本静态接合,因此,具有替代的模块的相关的新类加载器是有问题的。为了澄清,如果由216宣告的类使用由214宣告的类A,那么更新214将产生不与原类型A分配兼容的新类型A。因此,动态地修改类加载代表方案以使得与216相关的类加载器代表模块212的尝试将不成功。作为例子客户机类已通过使用新的类型与模块216中的类链接的情况将导致类固定例外和链接错误。然而,本发明提供从图I所示的设置解决问题的动态更新构架。并且,它成功地处理源自版本阻挡的所有类型相关问题[I],从而必需可在例如Java编程语言的当前的语义内无缝地出现跨着版本阻挡的模块通信。为了便于技术描述的理解,在本文的剩余部分中,以下的表示法适用。目标成分表示运行成分的最近的版本。在成分的连续的更新中,我们使用术语前面成分以表示成分中的任一个但不是目标。在更新时间上,当表示更新前后的目标成分时,分别使用术语当前目标和新目标。使用术语中间成分以表示目标和一些前面成分之间的特定的成分版本。作为例子,考虑成分A的四个版本:A1、A2、A3和A4。在这种情况下,A4是目标,并且所有其它的是前面成分。成分A2和A3是相对于Al的中间,A3是相对于A2的中间。并且,成分与在也已由214和216使用的形式A(n)上表示的更新的时间相关(如果适于给定的解释)。即使更新之间的时间差改变,定时也总是被表示为等距实数的线性次序。并且,作为对接成分,提到代表相同的初始展开的成分的两个版本的任何两个成分。除了这些时间相关术语以外,将成分平台自身的顶部的构建的任何用户特定成分说成可更新成分。在可更新系统的类级上,我们使用术语可更新类以描述在可更新成分中宣告的类。由本发明公开的动态更新方法的基本概念是In-Place Proxification技术。它是前面成分与目标之间的接合。In-Place Proxification机制对于在两个成分版本之间的间接引入的问题提供新颖的方案。在现有的间接机制采用将用于重新改变呼叫的方向的代码从旧的版本置于旧的成分周围的新版本的一般包裹器概念[4]的变体的情况下,In-PlacePiOXification机制使用适当位置产生的代码以向旧成分的代码内的更新的版本提供间接的水平。由此,重新定向从外面移动到内部,这基于一般的包裹器概念解决现有的方法面对的问题。主要思想是产生成分级开关以启用成分的代码内的代理行为。现在参照图3,该图是进入的对于304的请求如何通过由308表示的成分APl被截取并被转送到310的示图。该转送不能通过直接的通信出现,原因是它将与由于310中的新的明显的名称空间的产生出现的版本阻挡相交。出于这种原因,我们使用反射技术以从前面成分通信到目标。但是,反射不对于手边的问题提供完全的方案,原因是转送方法调用中的形式的参数类型和返回类型可能不与通过前面成分已知的类型兼容。一般地,以下描述的前提适用于在用于成功的转送的可更新类中宣告的方法。需要关于目标类获知每个可更新类。因此,实现本发明的本示例性的系统在其被 加载之前在每个应用类中产生类型java. lang. Class的静态域。在宣告成分的每个更新之后,在第一用途上设定该域。返回图4,该图表示成分更新被应用于402以及404之后的示例性的系统快照。由于可更新的形式参数类型未必与呼叫方法中的那些类型兼容,因此,在这种情况下找到正确的目标方法是麻烦的。因此,必须查找正确的类型,使得它们匹配目标方法的形式类型。现在,如果在成分D中宣告的方法即m使用成分E类型类作为形式参数类型,那么该类型不会符合目标成分E的名称空间即406。因此,402的名称空间中的类型应被使用以查找该方法。仅有的合理的获得的正确的类型版本的选项,不管来源如何,都要询问仅代表已知的类加载器的目标类的相关类加载器。每当出现方法调用,询问类的类加载器就引入不可接受的费用。它会对于各方法调用中的各可更新形式参数类型强制执行类加载算法。这是本发明高速缓存已直接在宣告的类中查找方法的原因。另外,它对于各可更新的成分保持已加载类高速缓存。在静态方法的情况下,目标类和方法足以支持方法转送。但是,在实例方法调用中,方法必须确定调用应被转送到哪个对象。通过特定标记器类型的代码产生的实例域,在可更新的类的每个实例中保持对于该目标对象的参照。通过字节代码变换,通过所有可更新的类实现标记器类型。我们用术语目标信息表示所有的上述的目标,即目标成分、类、方法和对象。但是,在静态方法背景中目标信息仅包含目标成分、类和方法的意义上,术语是依赖于背景的。找到正确的要转送到目标方法的参数与确定第一位置中的目标对象相同。不管版本如何,参数必须代表系统中的相同的实体。因此,根据由目标类理解什么类型,传输到目标方法的实际的参数可以是In-Place Proxies和目标对象的组合。现在参照图5,该图表示502的动态更新之后以及504的动态更新之后的模块连接的示例性的快照。除了方法体的发展以外,本发明还允许类接口和类型等级的动态发展。影响API类的类型的改变变得直接对于客户机的更新时的客户机成分可见。通过使与客户机成分的新版本508相关的类加载器直接代表其对于其成分从属506的目标成分的类加载,实现这一点。图5所示的设置还揭示关于总体性能的本发明的另一非常重要的性能。很显然,根据提到的前提的API方法的转送提出相对较大的性能损失。这主要由引入的反射行为导致。但是,一旦客户机针对更新的成分API被编辑并且然后与新的目标成分动态接合,这些调用将直接对于目标方法重新出现。由此,方法调用速度返回更新之前的速度。虽然先前的部分的In-Place Proxification技术实现跨着类加载器边界的通信,但是,它不通过自身保持程序一致性。如上面解释的那样,存在需要被处理以支持正确的执行流程的包含于转送中的类型有关问题。构架必须确保特定的目标成分中的任何活动对象由每个相应的前面成分中的零个或一个对象代表。零是由于仅在需要上产生相应的对象。例如,运行目标成分中的正常的构建器不触发该点上的前面版本中的任何其它的对象的产生。只有通过In-Place Proxy方法返回目标对象,才在其位置上构建和返回相应的对象。该相应的对象被预先配置为将所有的将来的方法调用转送到从中产生它的目标对象。为了确保已返回正确的对象,本发明提供根据其活动表现使对象成对的登记。本发明通过称为对接操作的技术操作对象的多个表现之间的对接。
在更新时间上,通过改变更新的成分的运行时间开关,更新成分的所有类和对象的行为变为In-Place Proxies。在第一用途上,注入的In-Place Proxy代码从通过新的目标成分宣告的类定义触发相应的未初始化的对象的构建,并且将这些对添加到适当的对接图中。并且,这触发被设为指向新的目的目标成分的相应的表现的目标对象和类域的初始化。在该点上,未初始化的对象表示前面的对象的状态不迁移到新的目标对象。在各单个域的第一用途上懒惰地出现状态迁移。上述的方案描述了如何产生并对于运行系统中的已存在的对象操作相应的对象。客户机可在发生更新之后继续产生前面成分的对象。在这种情况下,正如方法调用那样,构建器转送到目标成分中的相应的构建器。虽然这原则上执行两个构建器,但是,用户写入的构建器体仅在目标构建器中运行。另外,根据上述的对接操作映射来自这种对象构建的两个相应的对象。另一重要的事项是确保跨着成分边界的任何方法调用仅通过In-Place Proxy通过一个间接的水平。假定成分已被更新两次,并且,其对象通过In-Place Proxication过程两次。然后,当第一版本的客户机调用方法时,它将通过中间成分以到达目标成分中的对象。为了确保一个间接的水平,In-Place Proxy类保持对于其最后的已知的目标成分的静态转送参照。最终,该目标被更新,并且,其运行时间成分开关改变,以启用其宣告的类中的转送。这进行由初始的成分点向中间成分保持的转送参照,这是不希望的。因此,目标成分的当前的知识的简单的检查揭示新的目标成分已被安装,并且,转送参照在转送之前通过应用线程自身被更新。并且,也在对接操作中反映该元信息更新。状态迁移对于动态更新是中心。一般地,状态迁移技术落入以下策略中的一个中I)透明状态迁移和2)编程器影响状态迁移。本发明基于透明状态迁移。在我们的意见中,透明状态迁移优于编程器影响状态迁移,原因是它不需要明确写入的版本适配器或状态传送功能。写入版本适配器和状态传送功能是许多类型的更新不需要的高强度劳动任务。本发明使用自动并且透明地将前面成分的域值传送到目标成分的机制。该机制懒惰地按需执行状态迁移。在域的第一访问上通过应用线程将状态从前面成分传送到目标成分。由于不需要特定的锁定,因此,该方法保持标准同步化语义。由于不暂时停止线程,因此,僵局不是问题。
在更新之后,每个进入的请求在新的目标成分中结束,并且,最终,它将导致从前面版本传送状态。为了实现这一点,方法产生特定的访问方法,以操作域读取和写入。基本思想是,对于反映是否存在该状态的每个域保持Boolean值。在类加载和标准构建器调用时,这些域被设为错误(缺省初始化)。在这种情况下,由于任何状态首先处于初始的版本,因此错误反映存在状态。在从前面对象构建的新的目标类和对象中,这些域被明确设为正确。由此,它对于相关的访问方法表示不存在该状态。为了将状态传送到当前的目标类和对象,插入的访问方法查找前面相应 的版本,直到它在其相关的Boolean值中定位保持错误值的一个。然后,该域从前面版本被传送到目标并且Boolean值分别被设为正确和错误。由于只有非可更新类型可通过参照被复制,因此,该处理也依赖于找到的值的类型。如果它是可更新的类型,那么对接操作定位或产生对接对象。本发明的重要的性能在于,它支持类中的新域的引入。仅描述了迁移的对象的相关的Boolean值如何被明确地被设为正确。这不反映初始地在目标类和对象中实际存储新的域值的事实。出于这种原因,一旦对于第一时间调用特殊的得到器方法,它就结束尝试在前面版本中定位域。它将发现该特定的域已被添加,并因此校正Boolean域,如同该值已存在。但是,新的域不能自动地被分配给有意义的值。为了回避可能的零值指针例外或意想不到的缺省原始值,本发明通过程序器自身支持明确地在类水平上写入的域分配的初始化。对于通过编程器写入的每个类级分配,本发明确保从任何前面对象产生的新对象将保持由编程器分配的值。通过后面详细描述的字节代码分析实现这一点。已解释了方法如何操作二进制兼容变化,本部分描述它如何操作二进制不兼容变化。该方法模仿需要共同构成二进制兼容成分的更新组的线外更新方案。因此,该方法还支持破坏与它们的先前的版本的二进制兼容性的成分API的更新。作为例子,我们使用向现有的例子添加参数的公知的简单的例子。public void createlnstance (String name, int ID) {···}public void createlnstance (String name, int ID String description){..·}现在,尝试更新包含以上的方法的成分可导致破坏的客户机。因此,在执行更新之前,静态依赖性验证器定位这种不兼容成分变化。在例子中,假定验证器将找到去除的API方法变化。它然后尝试将更新定位到客户机成分,并且检查与客户机成分的更新的组的兼容性。如果它没有找到任何不兼容性,它实施新的一组的成分的更新。否则,它舍弃更新。引入二进制不兼容变化由此通过在客户机成分上施加要求影响运行系统的更新能力。这是独立开发的成分中的公知的限制。破坏由成分的原始版本设置的合同的成本是,方法不能在隐含的编程器在更新客户机上投入之前也在所有的运行的系统中施加更新。API设计者完全知道该成本。一般地,他们采取行动以保持二进制兼容性。例子是,他们将使Listing3中的方法超载,由此对于大量的源代码迭代保持旧的API。我们强调,该限制正是你从线离更新方案得到的,并且它与如何实施更新无关。任何引入更加智能的用于允许二进制不兼容变化的更新的机制的尝试将破坏编程器透明性。参照图6,该图是表示在系统启用602之前首先启动动态可用更新程序实例所需要的高级表现的流程图。在步骤604中,本发明的用户采取行动以执行计算机程序,其中,本发明应被实施。用户规定代表自举变换工具的特殊的代理库。该工具负责变换自举类的字节代码,这些类由虚拟机使用以启动代理库。在该点上,执行控制被操作到代理库606。特定的代理库在步骤608中通过询问所有加载的类的虚拟机确定一组自举类。在获得对于所有加载的自举类的参照之后,在步骤900中出现找到的自举类的字节代码的变换过程,在参照图9. I的同时给出其详细的描述。在变换过程之后,除了执行实施本发明的运行时间部分所需要的字节代码变换所需要的不同的特殊的变换代理以外,特殊代理库在包含变换的自举类的610中引起新的计算机程序实例。参照图7,该图是表示为了动态地更新活动运行系统中的模块采取的步骤的流程图。初始地,在702中,通过更新当前运行的系统中的模块的请求触发事件的流程。根据本发明的特定的实施例,动态更新请求的来源可以是可与本发明通信的任何事情。已启动动态更新过程,在步骤704中定位当前运行模块的模块的最近的版本。动态更新过程然后在在本发明的特定的实施例中增强的成分系统中安装新的模块,706。在708中,新产生的成分然后与类似地新产生的虚拟模块相关。这种虚拟模块代表安装于成分系统中的真实成分的特定的版本。由于它们具有用于从它们的自身的唯一类型名称空间即需检索相应的对象和类的内置机制,因此,它们用作相应的模块版本之间的结合。为了例示,在In-PlaceProxy方法调用中,如312中的一个那样,如果方法的参数属于304的类型名称空间,那么 它必须被转换为310的相应的类型名称空间。现在,在可出现312的代表之前,对于与在在304中截取的方法中给出的原参数值对应的对象询问与310相关的虚拟模块。如果这种相应的对象存在,即它立即被检索,否则,如上面描述的那样,作为未初始化的对象产生。返回图7,在使真实成分与虚拟模块相关之后,新的虚拟模块中的运行时间开关被初始地设置,以确保分别在相关的成分的唯一类型名称空间中构建和加载的对象和类不代表710。在712中出现先前的安装的模块的动态更新,这里,对于新安装的模块中的可能的将来的相应的表现,使用运行时间开关以使得任何对象和类为代理。最后,在714中,在本发明的特定的实施例中增强的成分系统中的特定的要素的资源的域特定更新。参照图8,该图是描述在本发明的实施例的执行中即需变换类所采取的步骤的流程图。初始地,在802中,类加载事件被触发,以将类加载到执行运行系统的虚拟机中。在步骤804中,变换代理确定类是系统类还是应用类。这里,类关于其类加载器被分类。应用类由下层的成分系统的成分类加载器加载,并且,系统类由系统类加载器加载。在参照图9. 6和图9. 10代表的更详细的示图的同时,分别详细描述1400和1800所示的变换系统类和应用类的高级过程步骤。类似地,在参照图9. 16的同时,全面描述与它们的类加载器无关地在系统中的所有类上执行进一步的字节代码修改的2600所示的高级变换步骤。一旦完成所有的字节代码变换,就在806中将修改的类加载到虚拟机中。现在返回图9. 1,该图是表示变换自举类的字节代码所采取的步骤的流程图。该流程由变换每个自举类的字节代码的自举过程902触发。由此,对于每个自举类重复由该流程图表示的过程。在904中,自举类中的需要特定的操作以完成本发明的某些性能的那些类被滤除。如果904中的决定产生正确,那么通过进一步在图9. 3中详细描述的单独的过程操作变换这些特定的类所采取的步骤(1100)。对于各非特殊自举类,通过以下的过程变换字节代码1)在906中存储关于自举域的信息,2)在908中通过方法和构建器迭代,根据它们是对象终化器1100、构建器1200、公共或保护方法1300变换代码。最终,通过2600捕获执行字节代码替代和其它的特定的字节代码指令操作的高级过程,在参照图9. 16的同时详细描述它。
图9. 2是示出执行在900中找到的特殊自举类的字节代码变换所采取的步骤的流程图。本发明的示例性的实施例替代这些特殊类中的某些方法的字节代码,以确保反射性机制的用途与上述 In-Place Proxification Correspondence Handing模型对应。在 1004中,如果要被变换的特殊的类是java. lang. Class类,那么处理分支到1006。处理然后在1008中搜索称为getDeclaredMethod或getDeclaredField的方法。在这些方法中,在方法的开始插入字节代码,以检查是否通过本发明添加搜索的域或方法,1014。在1016中,如果是这样,那么添加字节代码,以外加运行时间例外。返回1008,在java. lang. Class中的方法是getDeclaredField或getDeclaredMethod中的一个的情况下,处理分支到1010,在这种情况下,在1012中添加字节代码,以调用特殊的滤波器方法以在分别返回宣告的方法和域的列表之前实施通过本发明添加的任何方法或域。重新观看1004,在跟随“no”分支的情况下,处理在1018中寻找java. lang. reflect. Field类。在找到该类的情况下,在1020中定位称为getFieldAccessor的特定方法,并且,在该方法的开始在步骤1024中插入字节代码,以返回符合上述的本发明的域访问模型的顾客制作的域存取器。类似地,对于最后的特殊的类即j ava. reflect. ReflectionFactory,步骤1022定位在方法的开始插入步骤1024中的字节代码变换的特殊方法。
返回图9. 3,该图是表示确信仅在特定对象的最后版本上执行终化方法的原代码所需要的步骤的流程图。字节代码变换在终化器方法的开始插入字节代码,1102。插入的字节代码首先检查是否在可用更新的应用类中宣告其中执行终化方法的对象,1104。如果是,那么它进一步根据上述的Correspondence Handling对象检查对象是否是最后的版本,1106。在这种情况下,执行该终化方法的原方法体,1108。返回1104,如果当前终化的对象不是更新应用类的实例,那么也执行原方法体,1108。在1106中对象不是最后的版本的情况下,变换过程插入字节代码以在不执行原方法体的情况下立即返回,1110。在对象终化时排除原终化代码的原因在于,本对象的最后的相应的对象当前在系统中是活动。由此,来自终化方法的清除的任何可能的副作用会对于运行的系统具有不希望的语义影响。观看图9. 4,该图是表示确保在仅在特定对象的最后版本上执行构建器的原代码所采取的步骤的流程图。字节代码变换在构建器的开始插入字节代码,1202。插入的字节代码首先检查是否在可用更新的应用类中宣告其中执行终化方法的对象,1204。如果是,那么它进一步根据上述的Correspondence Handling对象检查对象是否是最后的版本,1206。在这种情况下,执行该终化方法的原方法体,1208。返回1204,如果当前终化的对象不是更新应用类的实例,那么执行原构建器,1208。在1206中对象不是最后的版本的情况下,变换过程插入字节代码以在不执行原方法体的情况下立即返回,1210。如果更新的类构建的客户机是该类的对象,那么一般出现这种情况。类等级中的构建器的强制链接强制第一字节代码指令为对于超构建器的调用。因此,即使插入的字节代码可解释对象是否是最后的版本,它也不能忽略超构建器呼叫。因此,当在描述的例子中进入超构建器时,产生的对象不是最后的版本,从而导致由In-Place Proxificated子类操作的构建器代表。返回图9. 5,该图是表示在方法的开始插入字节代码1302以确信总是在执行的对象的最后的版本中出现编程器写入方法体的执行所采取的步骤的流程图。插入的字节代码首先检查是否在可用更新的应用类中宣告其中执行方法的对象,1304。如果是,那么它进一步根据上述的Correspondence Handling对象检查对象是否是对象的最后的版本,1306。在这种情况下,执行原方法体,1308。返回1304,如果当前执行方法的对象不是可用更新的应用类的实例,那么执行原方法体,1308。在1306中对象不是最后的版本的情况下,变换过程插入字节代码以调用负责查找当前执行的对象的最近的相应的版本的方法1310。在获得了最近的相应的版本之后,对于目标类中的相应的方法,在步骤1312中代表原方法调用。观看图9. 6,该图是表示系统类如何在被加载时被变换1402的流程图。在将系统类加载到虚拟机中之前,字节代码被分析,1404。在类的分析中,如1406所示,对于读取和写入类中的非静止域产生两个特殊的存取器方法。当分别参照图9. 7 (1500)和图9. 8(1600)时,给出这些方法的产生的详细的描述。1408确定类是否被宣告为最终的类。在其它的情况下,流程通过步骤1700,它示出,在前进到1400之前,为了使得可能的可用更新的子类利用它们,需要在该类中产生一些助手方法。当参照图9. 9时,给出该产生的进一步的描述(1700)。返回1408,在类不是最终的情况下,处理在1410中通过方法和构建器迭代,从而根据它们是对象终化器(图9. 3)、构建器1200 (9. 4)还是公共或保护方法1300 (9. 4)变换代码。最终,通过2600捕获执行字节代码替代和其它的特殊字节代码指令操作的高级 处理(9. 16)。
返回图9. 7,该图是表示对于系统类中的非静态域访问产生域读取方法所采取的步骤的流程图,1502。首先,在1504中,产生用于产生的方法的存根。然后,在1506中,处理在最终的类上分支,对于该最终的类,在1508中在产生的方法中插入要直接读取域值的字节代码。由于对于最终的类可不存在子类,因此该优化是可能的。因此,没有In-PlaceProxy对象可从包含处理的系统类的类等级产生,从而确保处理的系统类中的域的安全的直接域访问。对于不被宣告为最终的类,处理将字节代码插入到产生的方法中,以检查是否在1510中可用更新对象的所有人对象。如果是,那么对象在1512中被投射到特殊的可用更新的标记界面。通过以下描述的字节代码变换对于每个应用实现该特殊的界面。在1514中,使用通过本发明的本实施例实现的特殊的方法以用“原对象”替代当前执行的对象。原对象被定义为通过执行标准构建器产生的对象。相反,通过本实施例产生的任何相应的对象不是原对象。通过在1516中将域投射到宣告类类型、在1518中读取域值从原对象读取域,并且通过在1520中根据域的类型插入适当的返回指令将该域返回到原域读取指令的呼叫方。返回图9. 8,该图是表示在1602中产生用于系统类中的非静态域访问的域写入方法所采取的方法的流程图。首先,在1604中,产生用于产生的方法的存根。然后,在1606中,处理在最终的类上分支,对于该最终的类,在1608中在产生的方法中插入要直接写入域值的字节代码。对于不被宣告为最终的类,处理将字节代码插入到产生的方法中,以检查是否在1610中可用更新对象的所有人对象。如果是,那么对象在1612中被投射到特殊的可用更新的标记界面。在1614中,处理插入字节代码以如上面描述的那样获得对于原对象的参照。通过在1616中将域投射到宣告类类型、在1618中将值从参数加载到产生的方法并在1620中将加载的值写入原对象中,将域写入到原对象。返回图9. 9,该图是表示系统类中的某些助手方法的产生的流程图,1702。这些方法是用于在用于可用更新的类的类等级中确定关于上述的目标信息的某些性能的用于结束递归超呼叫的方便方法。在步骤1704中,是否产生方法的产生处理是特殊的isMethodPresent方法。在这种情况下,插入到产生的方法中的字节代码总是返回正确,1706。对于其它的产生的方法,插入的字节代码总是返回错误,1708。现在返回图9. 10,该图是示出分析1804并且将在1802中初始化的加载类之前的应用类的字节代码变换成虚拟机的流程图。在1806中,变换处理插入通过系统中的所有应用类实现的上述的可用更新的标记界面。1808示出对于应用类中的各域产生域存取器方法的处理的高级示图,参照图9. 11和图9. 12,后面是其详细的描述。步骤2100表示产生字节代码以将由更新引入的域初始化为该类的前面版本的处理的高级示图。参照图9. 13给出该过程的详细的描述。在1810中由被变换的类宣告的每个成员根据它是终化方法1812、构建器1814、静态初始化器(<〈clinit>>) 1816、非静态公共或保护方法1818还是静态公共或保护方法1820通过专门的变换,其中,分别在图9. 3 (1100)、图9. 14 (2200)、图9. 15(2300)、图9. 16 (2400)和图9. 17 (2500)中综合描述其中的各单个的变换。返回图9. 11,该图是表示在应用类中产生域读取方法1902所采取的步骤的流程图。在1904中,插入到域读取方法中的字节代码首先检查当前执行的对象是否是当前的版本。如果是,那么,在1906中,它进一步检查是否在对象的该版本中存在域值。本发明的本实施例对于宣告类的各单个域关联分别保持对于在1906中提出的问题的答案的Boolean值的阵列。在步骤1908中,如果存在状态,那么读取域值并将其存储于局部变量中。然后,·执行查看是否在1906和1910之间的时间周期中出现了宣告类的更新的检查。在出现这种更新的情况下,如1914所示,将域读取请求委托给当前的目标版本,在对象所有人在在1904中检查条件时在第一位置中被更新的情况下,这也会是得到的事件。返回1906,在这种情况下,在所有人对象的相应的版本中保持域状态的当前的版本。在这种情况下,在1916中调用从其当前的位置迁移状态的方法。在1918所示的设计有跨着相应的对象同步化的能力的特殊的锁定机制下,出现在该调用。因此,虽然用于读取和写入域值的算法是无锁定的并由此是快速的,但是,在从In-Place-Proxy对象移动到最近的相应的版本的同时,状态迁移处理需要特殊的锁定。返回图9. 12,该图是表示在应用类中产生域写入方法2002所采取的步骤的流程图。在2004中,插入到域写入方法中的字节代码首先检查当前执行的对象是否是当前的版本。在步骤2006中,如果是这样,那么进一步检查是否在对象的该版本中存在域值。在步骤2008中,如果存在该状态,那么写入域值。然后,在2010中,执行查看是否在2006和2010之间的时间周期中出现了宣告类的更新的检查。在出现这种更新的情况下,如2012所示,将域写入请求委托给当前的目标版本,在对象所有人在在2004中检查条件时在第一位置中被更新的情况下,这也会是得到的事件。返回2006,在这种情况下,在所有人对象的相应的版本中保持域状态的当前的版本。在这种情况下,在2014中直接写入域值,并因此在2016中更新相关的Boolean值。在2018中,为了去除相应的对象明确地陈述以保持域值的最近的版本的引入的暂时不一致性,调用特殊的透明的陈述方法,该陈述方法定位域值的先前的所有人并清除值自身以及相关的Boolean值。还如2020所示,更新当前的对象所有人以及先前的所有人的Boolean值的过程需要上述的锁定机制。去除特定的域值的先前的版本中的状态的过程自身不确保对于该域的同时的访问的正确的语义。这是查看是否必需2010和1910所示的宣告类的更新的额外的检查的原因。观看图9. 13,该图是示出向从宣告的类的前面版本构建的对象分配用于新添加的域的编程人员书写的缺省域值所需要的步骤的流程图。为了捕获匹配编程人员书写的域分配的字节代码,在2102中分析构建器的字节代码。分析的构建器的前提在于,它不能是将构建委托给宣告类中的另一构建器的一个,在这种情况下,将不在构建器的代码中存在类级域分配。步骤2104包含确定宣告类是否是加载到虚拟机中的第一版本的检查。在这种情况下,假定相应的宣告类还没有被加载,由于不能存在前面版本中的相应的对象,因此,处理在没有任何字节代码产生的情况下结束。相反,如果分析的类具有相应的前面类版本,那么处理前进到2106,这里,跳过实现强制超构建器调用的第一指令。在步骤2108中,可在分析的同时存储字节代码指令的字节代码块的宣告。然后,在步骤2110中,通过读取构建器中的下一指令,开始字节代码指令。2112所示的算法的第一停止准则是,指令是否是PUTFIELD,由此分配给宣告类中的域值。在指令就不是I3UTFIELd的情况下,2118中的试验检查以查看当前的指令是否在类级上有效。类级上的有效的指令是作为域初始化分配的一部分可在构建器外面使用的一个。例如,在构建器外面不能进行加载分析的构建器的第一参数,因此,处理停止分析。它然后移动到步骤2116,该步骤2116在实现停止准则之前通过找到的字节代码块产生方法。返回2118,在这种情况下,可在类级上进行指令,在当前字 节代码块中存储指令,并且在2110中分析下一指令。重新观看2112,如果指令是PUTFIELD指令,那么算法分支到捕获在TOTFIELD中包含的域名是否已被操作的2114。如果是这样,那么算法停止并前进到步骤2116。如果域名是新的,那么将指令添加到当前的块并且存储该块。然后在步骤2108中初始化新的字节代码块,并且,如以上从步骤2110描述的那样,算法继续。图9. 14是表示用于可用更新的应用类中的构建器的字节代码变换的流程图。变换在方法的开始插入字节代码,2202。在2204中,插入的字节代码通过检查宣告的类是否是最近的版本开始。在2206中,如果是这样,那么插入的字节代码检查当前被构建的对象是否也是最近的版本。即使宣告的类是最近的类版本,对象也可以是更新的子类的实例,并因此需要步骤2206。在对象类似地是最近的版本的情况下,如2208所示,执行原构建器体,从而构建对象,如同插入的字节代码还不在那里。返回在2204和2206中进行的试验,如果这些试验中的一个得出对象或类不是当前的版本,流程在2210上继续。在该方案中,插入的字节代码需要确定指令是否应被委托给最近的类版本或者任何可能的子类是否将在从强制的超构建器呼叫返回之后操作委托处理。因此,在步骤2210中检查产生的对象是否是子类的实例,在这种情况下,构建器在2212中立即返回。在应在来到2214的本类中实现代理处理的情况下,在2214中决定当前的可用的元信息是否是最新的。如果是这样,那么在2216中出现代表,如果不是,则在前进到2216之前在2218中将目标信息更新。现在返回图9. 15,该图是表示在本发明的本实施例中变换静态初始化器所采取的步骤的流程图。如2302所示,在方法的开始插入字节代码。在步骤2304中,特殊的类登记处理被插入,以获得对于与系统中的类的成分相关的特殊的模块的参照。在整个示例性实施例中通过插入的字节代码使用该参照,以试验以查看类和对象是否被更新。在步骤2306中,插入的字节代码决定类是否是加载到虚拟机中的第一版本。如果是这样,那么在2308中执行类初始化器中的原代码。如果不是,那么方法立即在2310中立即返回,以不允许重新运行的类初始化器具有可能的不了解的副作用。图9. 16是表示用于可用更新的应用类中的公共和保护实例方法的字节代码变换的流程图。变换在方法的开始插入字节代码,2402。在2404中,插入的字节代码通过测试执行对象是否是最近的版本开始,在这种情况下,如2406所示,执行原方法体。在执行的对象不是最近的版本的情况下,为了成功地在2410中将方法委托给当前的目标方法,在2408中检查元信息,以查看它是否是最新的。如果目标指针不是最新的,那么流程前进到查找新的目标方法的2412。在通过动态更新去除相应的方法的情况下,如在2414中测试的那样,插入的字节代码返回以执行方法的当前的版本。否则,实施代表过程,其中,在后面在图9. 15(3300)中示出执行流程的详细的描述。图9. 17是表示用于可用更新的应用类中的公共和保护实例方法的字节代码变换的流程图。变换在方法的开始插入字节代码,2502。在2504中,插入的字节代码通过测试执行对象是否是最近的版本开始,在这种情况下,如2506所示,执行原方法体。在执行的对象不是最近的版本的情况下,为了成功地在2510中将方法委托给当前的目标方法,在2508中检查元信息,以查看它是否是最新的。如果目标指针不是最新的,那么流程前进到查找新的目标方法的2512。在通过动态更新去除相应的方法的情况下,如在2514中测试的那样,插入的字节代码返回以执行方法的当前的版本。否则,实施代表过程,其中,在后面在图9. 25(3300)中示出执行流程的详细的描述。观看图9. 18,该图是表示为了确保上述的发明后面的模型通过分析类内的所有的字节代码指令2602以捕获需要特殊的操作的指令在系统中的每个类上完成的字节代码变换的流程图。步骤2604滤除执行对象身份试验的字节代码指令,从而替代具有对于后面通过图9. 24详细描述的特殊方法的调用的那些(3200)。然后,在2608中,通过插入原始值的简单的比较,检查通过该方法返回的Boolean结果。在字节代码指令是在2610中测试的方法指令的情况下,方法指令如果并且只有方法是在2612中检查的特殊方法才被特殊的操作器方法替代,并进一步被2612的相关的注释规定。如果方法指令是对于克隆方法的调 用,那么根据当参照图9. 19时给出的详细的描述变换原字节代码(2700)。在方法指令与在示例性实施例中以Java为例的下层的语言的内置的同步化机制有关的情况下,根据在图
9.20中示出的处理变换这些字节代码指令(2800)。被截取的字节指令的最后的组是与通过2622测试的阵列相关的那些。如跨着相应的对象操作访问的2624所示,任何阵列长度的阵列读取、写入或询问被特殊的方法调用替代。通过图9. 27详细描述这些特殊的阵列方法的执行流程(3500)。现在返回图9. 19,该图是表示变换克隆方法调用的出现的字节代码所采取的步骤的流程图。初始地,在2702上,替代字节代码进入检查,以确定要被克隆的对象是否需要特殊的克隆操作。在后面通过图9. 26详细描述该检查的执行流程(3400)。如果如2704测试的那样需要特殊的克隆支持,那么执行流程调用执行基本的步骤的特殊的方法,以确保克隆的对象如2706所示的那样包含最近的状态。相反,如果不需要特殊的操作,那么如2708所示的那样执行原克隆方法指令。观看图9. 20,该图是表示由2802限定的同步化有关字节代码指令的替代的流程图。将在执行中在包含于堆栈上的特殊的对象上同步化任何同步化有关的指令。在步骤2804中,该对象作为参数被给予将返回跨着可能的相应的对象保持唯一性的该对象的唯一代表的特殊的同步化方法。然后,当原字节代码指令执行时,它将在可在以后通过可能参照不同的相应的对象的更新的类被解锁的对象上同步化。图9. 21是表示在加载到虚拟机中的可用更新的类的字节代码中变换域访问指令所采取的步骤的流程图,2902。如果指令不是GETSTATIC指令,那么,如2914所示,变换处理用于对产生的域访问方法的方法调用替代指令。在GETSTATIC指令的情况下,由字节代码指令规定的域所有人被检查,以在2906中查看是否它是界面,在这种情况下,原域指令得到保存。在任何其它的情况下,步骤2908检查规定的域所有人是否等于当前被分析的类。如果情况如此,那么,在2910中,处理检查是否在规定的类上实际宣告域。如果是这样,那么在步骤2914中,通过对于产生的域访问方法的调用替代指令。在2912中,如果不是,那么变换处理插入字节代码以执行运行时间检查,以确定宣告的域所有人是否具有用于该域的相关的产生的访问方法。如果从该方法返回的值是正确的,那么,如2914所示,域访问方法被调用。另一方面,如果在宣告的域所有人上不存在域访问方法,那么,在步骤2916中,使用原指令以检索域值。
返回图22,该图是表示变换字节代码、自举类内的域访问指令以及从其它的类到在自举类中宣告的域的访问所需要的步骤的流程图。在指令是在3002中测试的GETFIELD的情况下,变换插入在元件3032内示出的字节代码。首先,在3004中,插入的字节代码检查特定的域的所有人对象是否可用更新。如果是,那么通过调用特殊方法以检索对象所有人的原版本中的引导域,在3006中操作域访问。通过图9. 29在后面详细描述用于该引导域代表的执行流程(3700)。在从该特殊方法检索对象类型值之后,步骤3008确定域类型是否是原始的,在这种情况下,在3010中,字节代码要将返回的对象取出到其原始的对应部。否则,在3014中,CHECKCAST指令被插入以将对象投射到域类型。返回3004,在对象所有人不可用更新的情况下,插入的字节代码使用原GETFIELD指令以在3012中安全地直接读取域。在原指令是PUTFIELD的情况下,3018所示的插入的字节代码初始步骤要操作堆栈以将对象所有人放在堆栈上,由此能够在该对象执行进一步的检查。然后,在3020中,插入的字节代码检查对象所有人是否可用更新,在这这种情况下,在执行必要的步骤以应对3022和3024中的原始域类型之后,域写入在3026中被委托给特殊方法。在原域指令是对于域的静态访问的情况下,由于这些类不能被动态更新,因此,变换不需要插入任何字节代码。由此,静态域的状态被唯一地放置在宣告的自举类中。现在观看图9. 23,该图是表示变换系统类内的域指令采取的步骤的流程图。在域访问尝试访问在3012中测试的实例域的情况下,域指令被对于在步骤3104中产生的相关的域访问方法的调用替代。参照图9. 24,该图是表示操作前面提到的截取的特殊方法和动作3202所采取的步骤的流程图。在执行O对象身份比较,3204、2)Class. islnstance方法,3206、3)CHECKCAST 算子,3208、4) instanceof 算子,3210、5) Class. isAssignabIeFrom 方法,3212的变换的出现中的一个的情况下,为了实现上述的本发明的下层的模型的语义,本发明的示例性实施例的执行层执行特殊的行动。首先,在步骤3214中,执行层查找相应的实例,使得检查或动作的两侧在3214中均符合相同类型的名称空间。然后,在3216中,在这些实例上执行原代码的未修改的版本。返回3212,在触发执行层的执行是Class, getlnterfaces方法调用的情况下,在3218中,如果存在于从原getlnterfaces方法获得的界面的列表中,那么执行层滤除添加到可用更新的应用类上的特殊的界面。现在参照图9. 25,该图是表示代表从In-Place Proxy对象到最近的相应的版本的执行所采取的步骤的流程图,3302。在在3304中测试的构建器代表的情况下,执行层的流程在3306中开始,这是查看是否从更新的类去除了目标构建器的明智的检查。如果是这样,构建后退以执行在3342中启用代表处理的原代码。一旦从原构建器构建了呼叫方对象,它就将在宣告的类的成员的第一用途上变为In-Place Proxy,并且,将产生新的未初始化的相应的目标对象。在目标类中存在目标构建器的情况下,在3308中,来自原构建器的参数值被转换成目标的类型名称空间。然后,在步骤3310中,通过转换的参数调用目标构建器,并且,在3312中设置两个相应的对象之间的对接关系。在进入的代表请求如3314所示的那样是对于目标方法的情况下,执行层在3316中执行明智检查,以查看是否在更新的类中存在目标方法。如果是这样,那么参数如前面在3318中描述的那样被转换。否则,它在步骤3342中后退执行原方法。执行原方法。在步骤3320中,通过使用转换的参数调用方法,并且,如果方法的返回类型如在3322中测试的那样是空白的,那么处理结束。否则,在3324中,从目标方法返回的值被重新转换成符合呼 叫方方法的类型名称空间的相应的对象。在来自In-Place Proxy中的产生的域读取方法的域得到执行事件3326的情况下,在3328中,执行层通过执行明智检查以查看域以及由此而来的相关的产生的域读取方法是否仍存在于目标类中重新开始。在步骤3336中,对于域写入方法代表执行相同的检查。在存在目标方法的情况下,在步骤3330中出现反射调用,并且,在步骤3332中完成返回域值的转换。对于域写入代表,在步骤3338中,新域值被首先转换成新目标名称空间,然后,在步骤3340中反射性地调用相应的方法。观看图9. 26,该图是表示示例性实施例的执行层如何操作到来的请求以克隆对象或阵列的流程图,3402。在到来的请求是更早地由2702规定的isSpecialCloneNeeded的情况下,在步骤3406中,执行层首先检查要克隆的对象是否可用更新。如果不是这样,那么该方法在步骤3412中返回错误,从而表示不需要特殊的操作以克隆规定的对象。如果要克隆的对象可用更新,那么步骤3408检查是否将通过由java. lang. Object类宣告的自然克隆方法实施当前克隆调用。在这种情况下,方法在步骤3410中返回正确,从而信令需要特殊的操作以克隆对象。如在仅从上述的isSpecicalClone方法在正反馈上执行的3414中测试的那样,在这种情况下,到来的请求是specialClone方法。在步骤3416中,执行层然后产生未初始化的对象以变为克隆。在该新产生的对象上,在从现有的对象复制域值的步骤3418中横越层层次,从而确保域值首先在其相应的对象中的任一个中位于其当前的位置中。由此,克隆对象将包含与原对象相同的状态,但存储于原对象中的元信息都没有。在阵列克隆的情况下,执行层首先在3420中产生相同类型的原阵列的新的空的阵列。然后,在3422中,存储阵列的所有当前的元件的相应的阵列被横越,并且值被转换到新阵列成分类型的类型名称空间。现在参照图9. 27,该图是表示当执行阵列访问的修改的出现时在示例性实施例的执行层中采取的步骤的流程图,3502。在对于在3504中测试的阵列的长度询问执行事件的情况下,执行层首先定位在步骤3506中询问的阵列的原阵列。原阵列是通过应用代码产生的阵列的特定版本。原阵列总是在其自身类型名称空间中保持更新的元件值。然后,在步骤3508中,从原阵列检索阵列长度。在如通过3510检查的那样被执行的修改的阵列负载动作的情况下,执行层在3512中检索原阵列,通过使用在步骤3514中在原AALOAD中给出的指数从原阵列得到当前的值,并且在步骤3516中将该值转换成修改的字节代码的呼叫方的类型名称空间。在被执行的修改的阵列存储动作的情况下,执行层在3518中检索原阵列,在3520中将在原字节代码指令中使用的值转换成原阵列的类型名称空间,并且在3522中在原阵列中存储转换的值。观看图9. 28,在该图是表示操作用于检索杂散代码的修改的字节代码指令和对象的系统身份混列码的执行所采取的需要的行动的流程图,3602。在执行由3604检查的系统身份混列码的替代字节代码的情况下,执行层在3606中检索原对象,并且在3608中返回原对象的原身份混列码。在调用混列码方法的修改的版本的情况下,3610中的执行层首先检查以检查用于当前的对象的特定的混列码方法是否是在java. lang. Object类中宣告的方法。如果是这样,那么流程从已覆盖的步骤3606继续。如果对于特定区域对象覆盖混列码 方法,那么,在步骤3612中,请求委托给最近的相应的版本。由此,请求对象的混列码或身份混列码将总是对于相应的对象返回相同的结果。参照图9. 29,该图是表示代表引导域访问所采取的步骤的流程图,3702。在通过3704检查的读取引导域代表请求的情况下,执行层首先在步骤3706中检索原对象。然后,它在步骤3708中通过使用反射在原对象中读取值。在引导写入域代表请求的情况下,执行层首先在步骤3710中检索原对象。然后,它在步骤3712中通过使用反射写入给予原对象的值。图9. 30示出表示从前面版本向对象的最近的对接版本迁移状态的需要的步骤的流程图,3802。在步骤3804中,执行层首先查看与触发状态迁移的对象对应的所有对象。定位的相应的对象的列表被存储于称为previousObjects的变量中。然后,在步骤3806中,通过向称为previous的变量分配下一元素,横越该列表。然后,在3808中,执行层确定当前的元素(previous)是否坚持到状态的当前版本,在这种情况下,在步骤3810中,定位的版本中的值被转换成最近的相应的对象的类型名称空间。并且,转换的域被写入到最近的相应的版本中的域。然后,在步骤3812中,对于最近的相应的对象,设定用于规定各单个域值的存在的相关的Boo I ean值,并且,在步骤3814中,对于旧的域值所有人,清除该值。返回3808,在在横越的当前的元素中不存在当前的域值的情况下,重新检查相应的对象的列表,以在步骤3816中查看是否存在更多的要横越的元素。如果是这样,那么流程递归地返回步骤3806。在3818中,在没有找到更多的元素的情况下,执行层断定必须在类的最近的版本中新宣告特定的域。因此,通过更早地描述的用于向新宣告的域分配缺消息值的算法,域值包含分配给它的值。最后,参照图9. 31,该图是示出当最近的版本中的域写入第一次修改相应的Boolean值时清除先前的相应的对象中的域值所采取的步骤的流程图,3902。在步骤3904中,执行层首先查找触发重新存储为previousObjects的状态清除的执行的对象对应的所有对象。在步骤3906中,通过向称为previous的变量分配下一元素横越该列表。如果当前的元素保持由在3908中检查的相关的Boolean值规定的状态,那么对于在步骤3910中横越的特定的元素清除该值以及Boolean域,并且处理结束。在先前的元素不保存该状态的情况下,如果如在3912中测试的那样存在这种元素,那么搜索下一元素。在横越所有元素并且在它们中的任一个中没有找到状态的情况下,执行层在域为新时在步骤3914中通过,并且,因此,已唯一地仅在一个相应的对象中放置域值。参考文献[I]Sato Y. , Chiba S. :Loosely-separated〃Sister〃Namespaces in Java.In proceedings of ECOOPi 05.Lecture Notes in Computer Science,Vol.3586.Springer-Verlagj (2005)pp. 49-70。[2]Drossopoulouj S. , Wraggj D. , and Eisenbachj S. 1998. What is Java binaryCompatibility . In Proceedings of OOPSLAi 98. ACM pressl998,pp. 341-361。[3] Orso A., Rao A. , Harrold M. J. : A Technique for Dynamic Updating of JavaSoftware. In:proceedings of ICSM02,IEEE Computer Society 2002,pp.649-658。[4]Buchi M. , Week W. :Generic Wrappers. In proceedings of EC00P2000. Lecture Notes in Computer SciencejVol. 1850. Springer-Verlagj (2000)pp. 201-225。[5] Dmitriev M. : Safe Evolution of Large and Long-Lived JavaApplications. PhD thesis,Department of Computing Science,University ofGlasgow,Glasgow G12 8QQ,Scotland, 20010[6]Malabarba S.,Pandey R. , Gragg J. , Barr E.,and Barnes F. : RuntimeSupport for Type-Safe Dynamic Java Classes. In Proceedings of EC00P00. LectureNotes in Computer SciencejVol. 1850. Springer-Verlagj (2000)pp.337-361。[7] Subramanian S. , Hicks M. , McKinley K. : Dynamic Software Updates: AVM-centric Approach. In Proceedings of the 2009 ACM SIGPLAN conference onProgramming language design and implementation, ACM SIGPLAN Notices, Volume44,Issue 6,May2009, pp. 1—12。[8]GustavsonjJ. :Dynam ic U pdati ng of Com puter P rograms-ProposedImprovements to the JDrums Updating System, Rise publications 2005.[9]Bialek,R.,Julj E.,J. _G. Schneider, J. -G.,Jinj Y. : Partitioning of Javaapplications to support dynamic updates. In proceedings of APSEC04,IEEE ComputerSociety Press,pp. 616-623。[10] Hjalmtysson G. , Gray R. :Dynamic C++classes. In Proceedings of theUSENIX 1998 Annual Technical Conference, pages 65-76. USENIX Association, June15-191998。[II] Stanek J. , Kothari S. , Nguyen T. N. , Cruz-Neira C. 2006. Online SoftwareMaintenance for Mission-Critical Systems. In Proceedings of ICSM06,IEEE ComputerSociety 2006,pp. 93-103。[12]Chen H.,Yu J. , Chen R.,Zang B.,Yew P. :POLUS:A Powerful Live UpdatingSystem. In Proceedings ICSE07,IEEE Computer Society 2007,pp. 271-281。
权利要求
1.一种存在于活动运行的计算机系统中的类的先前的版本的所有活动对象向在从类的先前版本例示对象之后被动态加载的类的新版本的相应的对象的代理对象的明显的运行时间切换的方法,其中,对象身份和类类型可分配性在代理和对象和类的它们的共存的版本之间被共享,该方法包括 提供软件更新,其中,软件更新包含构成当前运行系统和新版本之间的差异的类定义的改变集合的字节代码; 通过明显地切换在变化集合中从类例示的当前活动对象的行为,执行活动运行计算机系统的非阻挡软件更新,以变为用于新类定义的将来即需的例示的相应的对象的非初始化的代理; 通过将字节代码注入自举类中使得对于更新的自举类的前面的版本的已例示的对象完成由更新的子类限定的扩展和/或推翻的行为,执行虚拟机特定自举类的启动前字节代码变换,以准备用于自举类的应用子类的将来的更新的自举类; 执行变换的自举类构成应用实例的新的一组虚拟机自举类的应用实例; 截断加载到虚拟机中的每个类的字节代码的加载,并且,一旦类加被启用,那么,在连续的相中, 变换类的字节代码,以对于相应的共存的对象和类启用共享的对象身份和类类型身份; 在替代之间通过将字节代码注入系统类中使得对于更新的子类的前面的版本的已例示的对象完成由更新的子类限定的扩展和/或推翻的行为,变换系统类定义即需的字节代码,以准备系统类的应用子类的将来的更新的系统类; 变换应用类的字节代码,以通过将字节代码注入应用类自身中从而使得实现应用类及其实例的运行时间切换,以变为以非阻挡方式自动传送身份和状态的将来的相应的对象和类的代理类和对象,使其可用更新。
2.根据权利要求I的方法,其中,在对于类的晚时的版本的对象的新的相应的版本的动态软件更新之后,活动对象的对象身份和状态在第一用途上成对,包括 构建更新的类版本的新的未初始化的对接对象; 构建相应的对象的唯一身份ID,从而确保对象的将来的增强的身份检查不管它们的特定的版本如何都对于相应的对象产生成立; 在类更新之后,从第一用途上的对象的前面的相应的版本迁移状态。
3.根据权利要求2的方法,其中,未初始化的对接对象自动地初始化对象状态的对于代理对象为新的一部分,包括将产生的字节代码方法插入初始化对于代理对象为新的状态的触发未初始化的对接对象的构建的部分的应用类中。
4.根据权利要求I的方法,其中,代表同一类的不同的版本的多个类可共存,包括 通过单独的类加载器加载更新的类,由此,代表相同的类的多个类型被加载到虚拟机中; 通过执行由共享相同的类型名称空间的相应的版本替代动态类检查动作的操作数的动态类类型检查的字节代码,替代执行由语言限定的动态类类型动作的类中的字节代码。
5.根据权利要求I的方法,其中,方法呼叫的转送将对象变换成将对于其成员的所有访问转送到相同的类的较新版本的新的相应的对象的代理中,包括变换类的字节代码确保参照多个相应的对象中的任一个的客户机将总是看到具有可从其自身的类加载器的可到达类型分配的类型的对象,包含 通过对于符合“instanceof”指令的右手侧操作数的类型名称空间的特定相应对象表现执行“instanceof”检查的字节代码,替代虚拟机字节代码指令“instanceof” ; 通过对于符合“CHECKCAST”指令的右手侧操作数的类型名称空间的特定相应对象表现执行“CHECKCAST”检查的字节代码,替代“CHECKCAST”的虚拟机字节代码指令等同; 将类和类的先前加载的版本的对象的运行时间切换成将任何将来请求重新引导到相应的新类和对象的代理,其中,从新的相应的表现获得的可能的值由符合代理成员的呼叫方的类型名称空间的代理表现替代,并且,插入用于控制重新引导处理的字节代码通过符合重新引导处理的接收器的类型名称空间的相应的表现替代由代理成员的呼叫方给出的参数。
6.根据权利要求5的方法,其中,从代理对象到相应的新的对象的方法呼叫的虚拟机表现的高速缓存能够实现有效的转送。
7.根据权利要求I的方法,其中,对象身份在相同的类的不同的版本的活动对象之间被共享,包含 变换类的字节代码以启用共享的对象身份,其中,用于比较对象的身份的虚拟机字节代码指令由通过使用属于相同的类名称空间的相应的对象版本执行身份检查的字节代码替代。
8.根据权利要求I的方法,其中,状态在从相同的类的不同的版本例示的多个相应的对象之间被共享,包括 薄记代表相同的对象的一组相应的对象中的哪个对象版本保持当前的单个共享的域值; 在一个按照宣告的实例域产生的得到方法和一个按照宣告的实例域产生的设定方法中在包裹域访问的系统类中产生字节代码,其中,插入得到方法中的算法包含 确保当在代理对象上被调用时,域将请求代理读取到初始地从标准构造器产生的相应的对象; 并且,其中插入设定方法中的算法包含 确保当在代理对象上被调用时,域将请求代理读取到初始地从标准构造器产生的相应的对象; 在自举类中产生替代字节代码指令的字节代码以用反射调用访问实例域,以访问初始地从标准构建器产生的相应的对象中的域; 在一个按照宣告的实例域产生的得到方法和一个按照宣告的实例域产生的设定方法中在包裹域访问的应用类中产生字节代码,其中,插入得到方法中的算法包含 确保当在代理对象上被调用时,域将请求向前读取到代理对象的最新的相应的版本,其中,从最新的相应的对象获得的域值被转换成代理对象的类型名称空间的域值; 确保如果当前不在最新的相应的对象中存在域值,那么在相应的对象中搜索域值并通过首先将其转换成最新的相应的对象的类型名称空间传送它; 确保如果在最新的相应的对象中存在域值,那么读取域值并且如果不存在平均时间的更新那么返回它;确保如果在读取域值之后出现宣告产生域得到方法的类的更新,那么它将读取请求转送到代理对象的最新的相应的版本,其中,从最新的相应的对象获得的域值被转换成当前代理对象的类型空间的域值; 并且,插入设定方法中的算法包含 确保当在代理对象上被调用时,域将请求转送写入到代理对象的最新的相应的版本,其中,从最新的相应的对象转送的域值被转换成最新的相应的对象的类型名称空间的域值; 确保如果当前不在最新的相应的对象中存在域值,那么写入域值并且找到事先保持域值的相应的对象并且请求其清除先前的状态; 确保如果在最新的相应的对象中存在域值并且如果不存在平均时间的更新那么写入域值; 确保如果在写入域值之后出现宣告产生域设定方法的类的更新,那么它将读取请求转送到代理对象的最新的相应的版本,其中,转送到最新的相应的对象的域值被转换成最新的相应的对象的类型名称空间的域值。
9.根据权利要求8的方法,其中,在由相应的对象共享的暂时锁定机制下执行从先前的版本向最新的相应的对象的状态的迁移。
10.根据权利要求8的方法,其中,在由相应的对象共享的暂时锁定机制下执行先前对接版本中的状态的清除。
11.根据权利要求I的方法,其中,共同同步对象对于对象及其代理对象的组确保对于线程的同步化访问,包括 变换类的字节代码,包含 通过在方法的开始插入MONITORENTER等同指令并在包含由于原始方法体中的未捕捉例外出现的离开点的方法的每个离开点上插入MONITOREXIT等同指令的字节代码,来替代内置的同步化访问修改器,其中,同步化的对象对于相应的对象和类是相同的; 通过对于相应的对象相同的唯一可识别对象交换同步化的对象的字节代码替代执行由语言限定的同步化的动作。
12.根据权利要求I的方法,其中,对象通过将对于其成员的所有访问转送到类的最新的版本的相应的对象变为代理对象,包括 在应用类中在各方法的开始插入字节代码,从而确保代理对象自动地使转送适于从可用的类的最新的版本例示的相应的对象。
13.根据权利要求12的方法,其中,通过在运行时间替代方法体的定义转送对于对象的访问。
14.根据权利要求I的方法,其中,活动对象在切换中在不阻挡当前执行对象内的代码的任何线程的情况下被动态切换成代理对象。
15.根据权利要求I的方法,其中,代理对象与从类的最新的版本例示的即需的构建的对接对象共享状态和身份。
16.根据权利要求I的方法,其中,代理对象与从类的最新的版本例示的即需的构建的对接对象共享状态。
17.根据权利要求I的方法,其中,代理对象与从类的最新的版本例示的即需的构建的对接对象共享身份。
18.根据权利要求I的方法,其中,代理对象的客户机对于代理对象的类的类型保持一个或更多个参照,但是通过代理成员向可用的最新的对接类版本的转送使用类的最新版本的方法体。
19.根据权利要求I的方法,其中,类的字节代码变换直接通过调用宣告类中的相关的产生的得到方法的字节代码替代读取对象状态的所有反射机构。
20.根据权利要求I的方法,其中,类的字节代码变换直接通过调用宣告类中的相关的产生的设定方法的字节代码替代写入对象状态的所有反射机构。
21.根据权利要求I的方法,其中,应用类的字节代码变换在类初始化方法的开始插入字节代码,以确保类初始化方法中的原始代码在类的前面版本已先前被加载到虚拟机中的情况下不被执行。
22.根据权利要求I的方法,其中,如果在宣告构建器的子类的代理实例上出现构建,那么类的字节代码变换在对象构建器的开始插入字节代码,以确保构建器即不执行原始代码也不将构建器调用重新引导到类的最新版本的相应的对象。
23.根据权利要求I的方法,其中,如果在代理实例上出现终化,那么类的字节代码变换在对象终化器的开始插入字节代码,以确保终化器既不执行原始代码也不将终化调用重新引导到最新的相应的对象。
24.根据权利要求I的方法,其中,类的字节代码变换通过确保产生的克隆包含与由被克隆的对象的所有相应的对象共享的状态等同的状态的字节代码替代由语言限定的克隆的出现。
25.根据权利要求I的方法,其中,类的字节代码变换通过最近的相应的对象替代串行化的对象的字节代码替代对象串行化的出现,其中,插入的字节代码确保共享的对象状态在继续串行化过程之前被传送到最近的相应的对象。
26.根据权利要求I的方法,其中,类的字节代码变换通过将访问请求重新引导到最近的相应的阵列对象的字节代码替代访问阵列的指令,包括 将由替代的阵列读取动作获得的值转换成呼叫方类的类型名称空间的值; 将要在替代的阵列写入动作中使用的值转换成最近的相应的阵列对象类型名称空间的值。
27.根据权利要求I的方法,其中,被动态加载的类的新版本的类型信息表示与类的先前的加载的版本不同的继承分层。
28.根据权利要求I的方法,其中,被动态加载的类的新版本的类型信息表示与类的先前的加载的版本不同的界面。
29.根据权利要求I的方法,其中,被动态加载的类的新版本中的方法宣告与类的先前的加载的版本不同。
30.根据权利要求I的方法,其中,被动态加载的类的新版本中的域宣告与类的先前的加载的版本不同。
31.根据权利要求I的方法,其中,类在编辑中被静态类型检查。
32.根据权利要求I的方法,其中,类由字节代码代表。
33.根据权利要求I的方法,其中,在不提供替代性的引导类路径的情况下开始虚拟机启用自举类的静态字节代码变换,包括 变换已加载自举类的字节代码; 在替代性的引导类路径上存储得到的修改的自举类; 在完成字节代码变换时放弃程序代码的任何进一步的执行,从而有效地使计算机程序结束。
34.根据权利要求I的方法,其中,在提供替代性的引导类路径的情况下开始虚拟机用替代性的一组自举类启用虚拟机的引导。
35.根据权利要求I的方法,其中,在不提供替代性的引导类路径的情况下开始虚拟机 启用自举类的动态字节代码变换,包括 变换已加载自举类的字节代码; 在替代性的引导类路径上存储得到的修改的自举类; 对于宣告虚拟机的特殊程序启动方法的所有非自举类截取字节代码的加载,以插入用于截取对于特殊程序启动方法操作的程序输入变元的字节代码; 籲开始新虚拟机实例,从而向其提供任何程序输入变元,任选的虚拟机变元包含替代性的引导类路径; 等待新的虚拟机实例终止并且一旦被唤醒就放弃程序代码的任 何进一步的执行从而有效地使计算机程序结束。
36.一种计算机程序产品,包括 计算机可用介质; 体现于所述计算机可用介质上、用于动态刷新活动运行的计算机系统内的软件模块的计算机可读指令,所述指令引导计算机以执行权利要求I 35中的任一项的步骤。
37.一种在计算机中实现的用于启用以静态键入的基于类的面向对象的编程语言书写的活动运行的计算机软件的非阻挡动态更新的系统,其中,类由字节代码代表,包括用于执行权利要求I 35中的任一项的步骤的装置。
全文摘要
根据本发明,提供在活动运行的计算机系统内的虚拟机上作为字节代码执行的静态键入的基于类的面向对象的软件的非阻挡动态更新的方法、计算机程序产品和系统。从现有的模块或多个模块例示的一组对象(字节代码表现的形式的应用资源和类定义的可识别的集合)准备好在活动计算机系统中的虚拟机上执行。出于更新运行的软件的目的,与已加载到活动运行的虚拟机上的那些对应的一个或更多个模块的新的版本被动态加载到虚拟机中。通过插入启用透明状态传送和类的前面版本与新版本的对象之间的共享对象身份的字节代码,对于动态更新准备加载的模块内的类定义。在软件更新的情况下,从更新类的前面版本例示的对象变为可能重新引导到它们的将来的相应的对象的未初始化的代理对象。在宣告类成员的第一访问上懒惰地产生相应的对象。除了对象和类的行为的懒惰重新引导以外,通过懒惰迁移实现非阻挡动态更新。
文档编号G06F9/445GK102725730SQ201080062492
公开日2012年10月10日 申请日期2010年11月16日 优先权日2009年12月18日
发明者A·罗达尔·格雷格森, B·诺雷加尔德·乔根森, M·拉斯马森 申请人:赛丹思科大学
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1