动态类封装的制作方法

文档序号:6597832阅读:131来源:国知局

专利名称::动态类封装的制作方法版权认可本专利文件所公布的一部分包括版权保护的内容。在专利和商标局的专利文件和记录中出现该专利文件或该专利公布的复件时,版权拥有者不会有任何异议,不过,若该专利文件或该专利公布的复件出现在别的地方,则版权拥有者将要追究其责任。相关应用的交叉参考本申请与美专利应用NO._____(AttorneyDocketNo.AP117HO)相关,该专利的提出日期与本申请的提出日期相同,名为“DYNAMICJAVACLASSLOADINGFORAPPLICATIONEXECUTION.”,该专利在此引用以供参考。
背景技术
:1
技术领域
总的来说,本发明有关一个可执行程序的软件工具的方法和装置,更具体的,用于识别模块,并将类与该可执行程序的每个模块联系起来。2相关技术描述无论对用户还是对软件公司来说,借助于一个分布式网络(例如因特网)下载应用程序都能提供诱人的利益。不过,随着应用程序复杂度和规模的增加,下载应用程序所需的时间也相应增加。不幸的是,由于下载时间的限制,拨号上网的用户不得不放弃通过因特网下载应用程序。图1举例说明了一个框图100,该图描述了在以前的技术中,从因特网下载一个可执行应用程序的方式,以便通过一个web浏览器(例如因特网ExplorerTM或NetscapeNavigatorTM)运行一个Java应用程序。服务器102有一个超文本标记语言(HTML)页104。该HTML页104借助于因特网,通过一个web浏览器110下载到用户108。一个ActiveX控制被包含在该web浏览器中或被下载给用户108。该ActiveX控制包含对象链接和嵌入(OLE)控制(OCX)114,一个包含Java程序和类文件的zip文件116,以及一个为系统提供安装OCX114和zip文件116所必需的信息的.inf文件。一旦执行了ActiveX控制,来自zip文件116的Java程序,OCX,zip文件和.inf文件就被封装为一个.cab文件。从而,ActiveX安装该.cab文件并解压该zip文件,并且通过web浏览器运行不同的Java应用程序。如前面参照图1所描述的,以前技术中下载应用程序的方法所带来的障碍使得用户放弃通过因特网下载应用程序。例如,利用一个56K的拨号modem,下载并安装一个典型的.cab文件大约需要5分钟。另外,在运行该应用程序之前,必须下载整个.cab文件。由于zip文件包含Java应用程序的所有类,因此,即使用户不使用其中的一些类,也必须等待下载完所有的类。随着软件功能的增强,或是软件中增加了更多的特定功能,由于.cab文件变大了,这一等待时间会变得更长。这一问题不仅在初次下载应用程序时存在,而且还扩展到对当前应用程序的修改中。例如,若对一个已经存在的程序进行1K字节的修改,以提供一个新的版本或更新,则用户不得不下载整个应用程序,或是接收一个带有已修订应用程序的磁盘。为节约开支,软件公司鼓励用户通过因特网下载文件,而不是提供新的或已修订应用程序的CD或软盘。由于与CD或软盘相关的费用最终仍归到用户头上,因此,能够方便地通过因特网下载应用程序对于用户来说也是有利的。尽管在有些情况下可以提供补丁,但对补丁的管理已变得很难处理,因此,不希望使用补丁进行更新。另外,补丁无法定位涉及该程序的最初下载的公司(?)。在从因特网下载一个可执行程序时,造成所需时间过长的另一个因素是,需要下载整个的程序,包括与该程序相关的所有特性函数。由于缺乏一种工具,可以将一个可执行程序划分为模块,并能知道在各个模块中每个类由该模块使用的情况,因此,需要下载整个应用程序。手工分析混杂代码以映射各种类和模块之间的相互作用这一工作所需的工作量是令人不敢问津的。随着程序的日益复杂,由于程序的规模更加庞大,手工分析更是无法轻易达到。即使代码中一个微不足道的改动也需要再执行一次全面的手工分析。另外,为了手工分析一个程序,必须能够获得该代码作者的专家意见,而在当前快速发展的环境下,很难满足这种奢求。因此,为解决上述问题,需要一种工具,按组将类结合起来,以生成能通过一个分布式网络(例如因特网)独立下载的可执行程序的模块。发明概要总的来说,本发明提供了一种监测工具的方法和装置,以满足这些需要,该监测工具用于记录并将一个应用程序划分为模块。应该理解,本发明可以多种方式实现,包括一个过程,一个装置,一个系统或一个设备。以下将介绍本发明的几个实例。在一个实例中,提供了一个用于识别一个可执行程序的模块的计算机实现的方法。该方法首先启动该可执行程序,随后,在该可执行程序运行期间对其进行监测。对该可执行程序的监测还包括,识别每个模块的相关类,这里,每个模块都对应于该可执行程序的一个特定功能。该监测还包括,在该可执行程序运行期间为每个模块生成一个数据结构。此处,数据结构定义每个特定功能的类。在另一个实例中,提供了用于生成一个类图的方法,类图表明一个可执行程序的模块怎样使用该可执行程序的类。一开始,在该可执行程序运行时,监测该可执行程序。随后,识别出与一个核心模块相关的每个类。核心模块用于运行程序的引擎。随后,在监测该程序的同时,执行与该程序相关的每一项任务。并记录每项任务执行中用到的每一个类。随后,为核心模块和每项任务定义一个类图,每个类图都定义核心模块和每项任务中类的相互关系。在本发明的另一个实例中,还提供了一种用于将一个可执行程序细分为自主类模块的方法,其中,每个模块都对应于一项任务。一开始,先运行该程序。随后,监测该程序的运行。接着,保留每项任务运行期间用到的类的记录。然后再定义每个模块的类图,这里,类图代表的是与每个模块相关的类的一个相互关系。在另一个实例中,提供了一种为一个应用程序开发一个软件工具的方法。该应用程序包括多个特定功能,每个特定功能都与至少一个类相联系。该方法一开始先识别该应用程序的每个类。随后,运行该应用程序的每个特定功能。然后识别与每个特定功能相关的每个类。然后为每个特定功能定义一个模块,这里,每个模块都包括一组所识别出的与一个特定功能相关的类。这里,每个模块都能够使与该模块相对应的特定功能得以实现。在本发明的另一个实例中,提供了一种用于生成一个应用程序的模块的方法。该模块能够自主地运行该应用程序的一个特定功能。该方法一开始是启动该应用程序。随后,请求一个用于装入一个类的类装入程序。接着,在装入该模块的每个类的同时监测该类装入程序。记录该模块的每个类。随后,检测一个终点(该终点表明该模块的所有类都已装入完毕)。接着,对该应用程序的其余模块重复该请求,监测,记录和检测操作。在另一个实例中,提供了一个计算机可读介质,其上存有用于生成类图的计算计指令。该类图表明一个可执行程序的模块怎样使用该可执行程序的类。该计算机可读介质包括用于在可执行程序运行期间对其进行监测的程序指令。还包括用于识别与一个核心模块相关的每个类的程序指令,核心模块运行的是该程序的一个引擎。该计算机可读介质包括用于在可执行程序被监测的同时执行与该程序相关的每项任务的程序指令。还包含用于记录每项任务执行时用到的每个类的程序指令。还包含用于为核心模块和每项任务定义一个类图的程序指令,其中,每个类图都定义了核心模块和每项任务中类的相互作用。本发明的优点很多。最值得一提的是,该监测工具允许在一个可执行程序运行期间对其细分。另外,本发明允许取一个复杂的程序并定义能够提供一个用户连接的自主程序,经一个分布式网络向用户的计算机独立地下载该程序的模块。结合附图,通过以下对本发明例子的详细介绍,可以清楚本发明的其它方面和优点。附图概述结合附图,通过以下的详细介绍,可以更好地理解本发明,其中,相似的参考符号表示相似的结构部件。图1举例说明了一个方块图,描述了以前从因特网下载一个可执行程序的方式,以便通过一个web浏览器运行一个Java程序。图2举例说明了一个流程图,描述了按本发明的一个实例,从因特网下载一个应用程序的方法。图3举例说明了一个更高水平方法的流程图,其中,一个Java加载器按本发明的一个实例下载并安装该应用程序。图4显示了一个方块图,举例说明了按本发明的一个实例,在图3的操作146中下载的模块列表。图5举例说明了一个流程图,显示了按本发明的一个实例,在应用程序运行时根据需要下载并安装其模块的方法。图6举例说明了一个流程图,更详细地描述了按本发明的一个实例,下载应用程序的模块的方法。图7示出了了一个流程图,更详细地描述了图6中的操作190,其中,按本发明的一个实例,通过一个类装入程序线索定位一个包含所请求类的模块。图8示出了了一个流程图,该流程图表示按本发明,在主应用程序启动的情况下,在多线程环境中执行后台下载的方法。图9是一个方块图,代表按本发明的一个实例,一个应用程序要被下载的各模块的优先列表。图10示出了了一个流程图,更详细地描述了图7中的操作208,其中,按本发明的一个实例,在下载管理器逻辑下,在一个多线程环境中下载一个模块。图11示出了了一个流程图,显示了按本发明的一个实例,用于监测一个可执行程序的类的安装的方法,以便为该程序的各特定功能生成模块。图12A示出了了一个方块图,描述了按本发明的一个实例,构成一个应用程序的模块的类的列表。图12B举例说明了按本发明的一个实例,图12A的模块1的类图。图13举例说明了按本发明的一个实例,在一个应用程序执行时监测程序的部分输出。图14举例说明了按本发明的一个实例,监测程序从一个贺卡应用程序捕获的核心模块的类的部分列表和GIF文件。推荐实例详述本发明描述的是一个软件工具,该软件工具能识别一个可执行程序的单独的组中或模块中使用的类,以协助从因特网有效地下载该可执行程序。不过,本技术专业人员很清楚,在实现本发明时,可以不要这些具体细节中的一些或全部。另一方面,为了更清楚地描述本发明,一些熟知的处理操作此处不进行详细的介绍。本发明的实例提供了一种方法和一种装置,用于由因特网及时下载应用程序。为加速一个程序的下载,在本发明的一个实例中,首先将该程序划分为软件类模块。模块的选择原则是,使每个模块都包含执行一个指定的程序任务时所必需的所有类。如此处所用到的,能够有效地处理并下载一个应用程序或组件的实例对任意类型的应用程序和应用程序组件来说都是通用的。不过,为便于解释,以下将参照一个打印机和该打印机的用户可以采用的应用程序选项。这些应用程序和选项可以在卖主的网址(例如)得到。例如,一个模块可以包含用于生成一个图形用户接口(GUI)的所有类。另一个用于选择并下载图像,第三个用于打印,第四个用于旋转或剪切一个图像,等等。至少一个模块必须包含运行该实例中应用程序的引擎所必需的核心类。核心模块可以从命令总线接收指令,或者,核心模块最好下载并安装GUI以便为用户提供更方便的接口。当要下载一个应用程序时,只有比整个可执行程序小得多的核心模块被下载。很自然,下载核心模块的时间比下载整个文件的时间短得多。在一个实例中,核心模块随后下载并安装GUI模块,该模块能为用户提供不同的程序选项。在运行该程序时,当用户选择不属于核心模块一部分的选项时,核心模块检查是否可以在本地获得能够实现所选选项的模块。若无法获得所要求模块,则从web下载所要求模块并自动卸载到正在运行的程序中。在方法的描述见于美专利申请NO.______(代理人档案号AP117HO)。为有效地下载该可执行程序,需要将该程序适当地划分为自主类模块。随着程序的日益复杂,已逐渐不可能识别出指定任务或任务组所使用的所有类。本发明通过提供一个监测工具(用来记录该程序的模块所使用的类)来将大量的类细分到自主模块中。在一个实例中,在一个软件包完成并可使用之后,一个监测程序观察该软件包的执行,并记录在所选任务执行期间用到的所有类。如以前所提到的,应用程序及其选项可以是可由一个或多个处理实体执行的任意类型的应用程序。在一个与个人电脑相连的打印机的例子中,所选任务可以是与打印或编辑图像或文本文件相关的任务。更具体的,可以包含诸如旋转,打印,调色,插入文本之类的任务。随后,监测程序为每个任务定义模块,其中包含实现该任务时所使用的所有类。在本发明的另一个实例中,来自多个模块的重复类可被移入一个公用模块中,或只放在最频繁使用的模块中。需要使用附加类的不完整的模块与包含其所需类的目标模块保持链接。或者,多个模块公用的类可被插入核心模块,这样,在最初下载核心模块以运行该应用程序的引擎之后,这些类总是可用的。图2举例说明了流程图122,综述了按本发明的一个实例,从因特网下载一个应用程序的方法。流程图122由操作124开始,这里,访问提供应用程序选项的网址。如以前提到的,应用程序及其选项可以是可由一个或多个处理实体执行的任意类型的应用程序。在一个与个人电脑相连的打印机的例子中,一个应用程序可以包含用于生成贺卡,邀请函,书的封面,艺术样板,公文卡片,礼品包装,礼品盒等的功能。随后,执行操作126,此处,从选项列表中选择内容范畴。用户从操作124中选择上述应用之一,并呈现给用户一个内容范畴列表。例如,用户可以选择制作一个贺卡,随后,呈现给用户的是一个该贺卡要使用的内容范畴的列表。当然,这里可以呈现适用于一个贺卡的任意数量的图像,例如,一个花纹排列,一个印刷,一个电影明星照片等。随后,在操作128,提供选定内容范畴的图像选择。在一个实例中,该图像被存入一个数据库。之后,该方法进入操作130,记录选定图像的标识符。这里,该图像被存储以便随后由Java应用程序使用。继续介绍图2,在操作132,收集打印机和纸张信息。在一个实例中,收集打印机型号,纸张尺寸,页边距信息等。接着,在操作134中,下载一个引导装入程序,此处,web浏览器下载并安装一个.cab文件,该文件用于装入一个Java应用程序和与该应用程序相关的各种模块。在操作136中,为用户呈现一个安全性选项。在一个实例中,若用户拒绝该安全性选项,则该方法中止。假设用户接受了该安全性选项,则该方法接着执行操作138,web浏览器解压并安装引导装入程序,即,.cab文件。随后,在操作140中,执行引导装入程序。在一个实例中,该引导装入程序的形式是一个ActiveX控制。在步骤142中,引导装入程序启动一个Java加载器。在一个实例中,该Java加载器包含在.cab文件中。如以下将详细介绍的那样,Java加载器能以有效便利的方式下载所期望的应用程序,即使用户使用的是相当慢的因特网连接。即,该应用程序马上可以使用,不管一个任务所需要的全部组件是否下载完毕。图3示出了流程图144,该流程图描述了一个高层方法,其中,按照本发明的一个实例,Java加载器下载并安装应用程序及其组件。该方法由操作146开始,在该操作中,下载由操作124的应用程序使用的模块列表。在一个实例中,该模块列表包括模块的名称及模块的版本信息。在图4中给出了一个模块列表的例子,以下将详细介绍。图4中,方块图158示出了按照本发明的一个实例,在图3的操作146中下载的模块列表。应该理解到,方块图158的模块列表仅仅举了一些模块的例子,根据软件应用程序及其应用,可以存在任意数量的模块。考虑以前所说的应用程序160,显示了核心模块和多个非核心模块。此处,核心模块版本1162已经由核心模块版本2164代替。因此,在图3的操作146中下载的模块列表只包含最新版本的核心模块,即,版本2164。应该理解,显示核心模块版本1只是为了起示出了的作用。图4的列表还包括模块1-5,由方框166-174表示。在本发明的一个实例中,将该应用程序所使用的模块列表与本地系统上的模块进行比较,以确定系统需要下载哪些模块。返回图3,进入操作148,Java加载器检查列表中的每一个模块以确认该模块是否在本地系统中存在。例如,检查图4中的每个模块,即,模块166-174,以确认它们是否已出现在本地系统内。接着,在操作150中,不安装操作148识别的任何旧的模块版本。例如,若本地系统已从该应用程序的以前使用中装入了核心模块版本1162,则此处就不再对其重新安装。另外,若在本地系统中存在任何老版本的非核心模块,则这些模块不再安装。在一个实例中,若旧版本的非核心模块是一个共享模块,则不再安装该非核心模块。随后,进行判定操作152,确定最新版本的核心模块是否在系统上。若不在,则在操作154中下载并安装该最新版本的核心模块。在本发明的一个实例中,核心模块包含具有入口点的类。在本发明的另一个实例中,Java加载器请求具有入口点的类以启动核心模块的下载。若最新版本的核心模块在系统上,则进行操作156,启动该应用程序。图5示出了流程图176,该流程图描述了按本发明的一个实例的方法,即,在应用程序运行时,根据需要下载并安装模块。流程图176由操作178开始,在本地系统上运行该应用程序。应该理解,在用户运行该应用程序并使用不同的功能时,最终将需要除核心模块之外的一个模块。继续以上有关一个打印机的例子,对于一些诸如打印,编辑,格式化等之类的操作,将需要不包含在核心模块内的类。随后进行操作180,识别包含所需要的类的模块。在操作182中,在本地系统上下载并安装包含所要求类的模块。例如,参照图4,若该应用程序的一个特定功能需要模块4172,则下载并安装模块4172。继续操作184,执行由所下载模块的类所提供的特定功能。在操作184之后,返回操作178,继续运行该应用程序。当然,该应用程序的组件一般在后台运行。一个用户可以根据需要中止或退出该应用程序。图6示出了了流程图186,该流程图更详细地描述了按本发明的一个实例,怎样下载该应用程序的模块。流程图186由操作188开始,从Java虚拟机(JVM)接收一个请求。例如,当最初开始该应用程序时,一个类装入程序将从Java虚拟机接收一个请求,运行一个实例中的主类。在另一个实例中,该主类包含在核心模块中。应该理解,Java虚拟机关心的是类而非模块,而类装入程序将类映射到模块中。随后,执行操作190,找出包含该类的模块。操作190将参照图7详细介绍。接着,在判定操作192中,判断操作190中找出的模块是否已安装在本地系统上。若没有,则在操作194中下载并安装该模块。若该模块已安装在本地系统上,则该方法从操作192进到操作196,从该模块获得所希望的类对象。图6的方法从模块获得类对象之后,该方法返回操作188。在一个实例中,类对象被返回给Java虚拟机。应理解,在该应用程序初始装入本地系统中时,包含入口点的类请求下一个类,依此类推,直到相关的类全部装入。在一个实例中,包含入口点的主类被映射到核心模块中。按一个所举的例子,类A包含入口点,一旦初始化,Java虚拟机首先请求类A。类A又请求类B,依此类推,直到构成核心模块的所有相关类都已装载完毕。以上所举例子也同样适用于完成特定功能的其它非核心模块。一旦包含核心模块的类被装入,用户可以选择要求特定功能的任务。在一个打印机及其应用的例子中,用户可能希望旋转或打印一个图像。一旦触发了旋转或打印按钮,则该代码将向Java虚拟机请求能允许特定功能的类。因此,Java虚拟机将请求该特定功能所需要的类,对于所请求的类及其所有相关的类重复操作188-196。如以下将参照图8-10详细介绍的,在另一实例中,允许特定功能的模块可以在被用户请求之前,在后台被下载。流程图190从操作198开始,Java虚拟机请求类装入程序装入一个类。接着进行操作200,搜索已装入的模块,寻找所请求的类。本技术专业人员可以理解,Java虚拟机可以使用多种技术搜索所请求类的数据结构。随后,进行判断操作202,确定是否找到了所请求的类。若在已装入本地系统的模块中找到该类,则在操作194中,该类被返回给Java虚拟机。若未找到该类,则图7中的方法进入操作206,查询服务器哪个模块包含所请求的类。在一个实例中,每个类都与服务器上的一个模块相联系,即,服务器具有一个数据结构,该数据结构将类与模块相匹配。因此,在本发明的一个实例中,此处识别包含所请求类的模块。在操作208中,下载包含所请求类的模块。在一个实例中,如参照图6所描述的那样,逐个相关类地下载该模块。在另一个实例中,还安装已下载的模块。下面的表1包含的是示出了代码,用于按本发明的一个实例安装该模块。当然,该代码可以采用任意格式,只要能完成安装功能就行。表1<prelisting-type="program-listing"><![CDATA[*Copyright1995-2001EPSONPaloAltoLaboratory.AllRights  Reserved.  //装入包含在Zf.中的包  publicstaticvoidinstallPackage(FilezFile)throwsIOException{  ZipFilezf=newZipFile(zFile);  try{  ArchiveInfoai=newArchiveInfo(zf);  //保存源文件  for(Enumeratione=zf.entries();e.hasMoreElements();){  ZipEntryze=(ZipEntry)e.nextElement();  StringzipName=ze.getName();  if(!zipName.endsWith(“.class”)){  ze=zf.getEntry(zipName);  zipName=zipName.replace(‘\\’,’/’);  InputStreamis=zf.getInputStream(ze);  if(ai.isSharedModule()){  saveResource(SmartLauncher.getSharedResourceDir(),zipName,is);  }else{  saveResource(SmartLauncher.getAppResourceDir(),zipName,is);}  }  }//搜索系统类文件并将它们装入共享类目录  for(Enumeratione=ai.getSystemClasses().elements();e.hasMoreElements();){  StringsysClass=(String)e.nextElement();  ZipEntryze=getZipEntryFromClassName(zf,sysClass);  if(ze==null){  thrownewIOException(“Cannotfindsystemclass”+sysClass);  }  InputStreamis=zf.getInputStream(ze);  saveClass(SmartLauncher.getSharedSystemClassDir(),sysClass,is);  }  //搜索系统类文件并将它们装入共享类目录  for(Enumeratione=ai.getSystemResources().elements();e.hasMoreElements();){  StringsysResource=(String)e.nextElement();  ZipEntryze=zf.getEntry(sysResource);  if(ze==null){  thrownewIOException(“Cannotfindsystemclass“+sysResource);  }  InputStreamis=zf.getInputStream(ze);  SaveResource(SmartLauncher.getSharedSystemClassDir(),sysResource,is);  }  //调用安装函数  if(ai.getMetaClass()!=null){  try{  InstallClassLoaderinstallLoader=newInstallClassLoader(zf);  ClassclsMeta=installLoader.loadClass(ai.getMetaClass(),true);  Objectmc=clsMeta.newInstance();  Class[]clsParams={java.util.Hashtable.class};  Methodm=clsMeta.getMethod(“install”,clsParams);  Object[]objParams={createInstallProperties(getSmartClassLoader(),zf)};  //调用安装函数  m.invoke(mc,objParams);  }catch(Exceptione){  //不能调用meta类安装  System.out.println(“Installfunctionignoredinclass“+ai.getMetaClass());  }  }  }finally{  zf.close();  }]]></pre>图8举例说明了流程图210,描述的是一个按本发明一个实例的方法,用于在主应用程序开始运行的情况下,执行多线程环境中的后台下载。应该理解,流程图210中的方法可利用参照图7描述的方法在多线程环境中操作。流程图210的开始是操作212,访问要下载的模块列表。在一个实例中,该模块列表包括一个优先级列表,该优先级列表代表的是模块在后台环境下载的顺序。以下参照图9描述了一个优先级列表的例子。图9举例说明了方框图224,代表按本发明的一个实例,为一个应用程序下载的各种模块的一个优先级列表。如框图224所描述的,包含该应用程序的每个模块被指定一个优先级。例如,核心模块(Mc)226被指定优先级为1,是最高优先级。核心模块必须被首先下载,因此,Mc必须接收最高优先级。其余模块M1-M5分别被指定优先级2-6。在一个实例中,该优先级列表被保存在一个联网资源服务器中(例如,它包含该应用程序及其模块)。如以下将进一步解释的,本地系统在以前执行该应用程序时,可能已安装了其中的一些模块。在这种情况下,初始设置给下载管理器的是需要下载的模块的列表,从而确保下载管理器不再下载已安装的模块。在本发明的一个实例中,该模块列表还可以是图4中的模块列表,其中包含优先级。返回图8,一旦在操作212中取得了优先级列表,则进行操作214,检查是否所有的模块都已被下载到本地系统上了。此时,检查参照图3,4和9描述的列表,以确定需要下载哪个模块。若列表中的所有模块都已安装在本地系统中了,则在操作216,该方法结束。若没有,则继续执行操作218,得到要下载的一个模块的名称。例如,若在本地系统中已经存在Mc和M2,则在操作218中得到M1的模块名,这是因为,M1是剩余模块中优先级最高的。在操作220中,下载与在操作218中得到的模块名相对应的模块。随后在操作222中安装所下载的模块。应该理解,按本发明的一个实例,表1中用于安装模块的示出了代码可以在操作222中执行。包含操作214-222在内的循环重复执行,直到下载完所有的模块。图10示出了了流程图230,更详细地描述了图7的操作208。此处,按本发明的一个实例,在下载管理器逻辑下,在多线程环境中下载一个模块。流程图208由操作232开始,下载管理器请求要下载的模块。应该理解,类装入程序在此处也有控制。在判定操作234中,判断所请求的模块是不是下载管理器正在下载的模块。若是,则接着执行操作236,该方法一直等待,直到下载管理器下载完该模块。应该理解,在该操作中可以使用本技术中熟知的通用等待技术。在图10的判定操作234中,若所请求的模块不是下载管理器正在下载的模块,则进入操作240,当前的下载操作暂停。例如,一个用户希望旋转一个图像,需要模块4(M4)来完成该特定功能。不过,下载管理器正在下载的是模块3(M3)。则在操作240中暂停M3的下载,从而可以下载M4,而不会与M3竞争带宽。在本发明的一个实例中,只有在用户中断由优先表控制的顺序模块下载时,才启动包含该判定操作的下载管理器逻辑。在操作242中,下载所请求的模块。继续上面的例子,此处,在暂停M3时将下载M4。在一个实例中,另一个下载M3的代码例子被用于下载M4。在操作244中,安装所请求的模块。接着,该方法执行操作246,恢复被中断下载的线程。参照上面例子,在安装了M4之后,恢复M3的下载。随后,在操作248,该方法开始图8中的操作220,下载该模块。下面的表2包含按本发明一个实例的类装入程序的示出了代码。当然,该代码可以取任意格式,只要能完成类装入功能就行。表2<prelisting-type="program-listing"><![CDATA[/*  ″  *$WorkfileSmartClassLoaderjava$  ″  *  ″  *Copyright1995-2001EPSONPaloAltoLaboratory.AllRightsReserved.  ″  *EPSONResearchandDevelopment,Inc.ASeikoEPSONSubsidiary.*Allrights  reserved.  *  */  packageepal.compman;  importjava.util.*;  importjava.util.zip.*;  importjava.io.*;  importjava.net.*;  importjava.lang.*;  importjava.lang.reflect.*;  /**  *以下是类描述。  **  */  publicclassSmartClassLoaderextendsjava.lang.ClassLoader{  //从类名到所装入的类对象的映象。  privateHashtablem_classCache=newHashtable();  //从包名到档案文件的映象。  privateHashtablem_packageMap=newHashtable();  //从类名到档案文件的映象。  privateHashtablem_classMap=newHashtable();  //从资源名到档案文件的映象。  privateHashtablem_resourceMap=newHashtable();  publicSmartClassLoader()throwsIOException{  super();  }  publicURLgetResource(Stringname){  URLurl=getSystemResource(name);  if(url!=null)  returnurl;  StringszResourceFile=name.replace(′/′,File.separatorChar);  Filef=newFile(SmartLauncher.getAppResourceDir(),szResourceFile);  try{  returnnewURL(″file″,″localhost″,f.getAbsolutePath());  }catch(Exceptione){  returnnull;  }  }  publicInputStreamgetResourceAsStream(Stringname){  IiputStreamis=getSystemResourceAsStream(name);  if(is!=null)  returnis;  StringszResourceFile=name.replace(′/′,File.separatorChar);  Filef=newFile(SmartLauncher.getAppResourceDir(),szResourceFile);  try{  returnnewFileInputStream(f);  }catch(Exceptione){  returnnull;  }  }  protectedClassloadClass(Stringname,booleanresolve)throwsClassNotFoundException{//System.out.println(name);  if(name.indexOf(″PIMJpegNative″)!=-1){inti=10;  }  if(name.indexOf(″JopsDecoder″)!=-1){  inti=10;  }  //检查以前是否已装入该类。  Classc=(Class)m_classCache.get(name);  if(c!=null){  if(resolve){  resolveClass(c);  }  returnc;  }  ArchiveInfoai=(ArchiveInfo)m_classMap.get(name);  if(ai!=null){  //检查该存档信息的版本。  //窃用假设总是OK。  //可从Zip文件装入该类。  //现在检查是否应从系统装入该类。  if(ai.getSystemClasses().indexOf(name)!=-1){  //这是一个应由系统的类装入程序安装的类。  c=findSystemClass(name);  }else{  //从Zip文件装入。  ZipEntryze=SmartLauncher.getZipEntryFromClassName(ai.getZipFile(),name);  try{  c=loadClassFromZipEntry(ai.getZipFile(),ze,name);  }catch(IOExceptione){  thrownewClassNotFoundException(″Cannotfindclass″+name);  }  }  }else{  //不能从Zip文件装入该类。  try{  //尝试由系统装入。  c=findSystemClass(name);  }catch(Exceptione){  //无法从Zip文件或系统装入该类。  //这个类可能是  //1.未找到的分类请求资源束。  //2.应被下载或安装的一个类。  if(isResourceBundleClass(name)){  //VM请求一个封装的打包类。  thrownewClassNotFoundException();  }//系统找不到该类,尝试下载并安装该类。  try{  Filef=SmartLauncher.getDownloadManager().getZipFile(name);  SmartLauncher.getSmartClassLoader().loadPackage(f);  }catch(Exceptionioe){  thrownewClassNotFoundException(ioe.getMessage());  }  ai=(ArchiveInfo)m_classMap.get(name);  if(ai==null){  //我们在此处应发现该类。  thrownewClassNotFoundException();  }else{  try{  if(ai.getSystemClasses().indexOf(name)!=-1){  //这是一个应该由系统类装入程序装入的类。  c=findSystemClass(name);  }else{  //从Zip文件装入。  ZipEntryze=SmartLauncher.getZipEntryFromClassName(ai.getZipFile(),name);  c=loadClassFromZipEntry(ai.getZipFile(),ze,name);  }  }catch(Exceptionex){  thrownewClassNotFoundException(ex.getMessage());  }  }  }  }  if(resolve){  resolveClass(c);  }  m_classCache.put(name,c);  returnc;}publicvoidloadPackages()throwsIOException{  Filedir=SmartLauncher.getAppDir();  String[]zfname=dir.list();  if(zfname!=null){  for(inti=0;i<zfname.length;i++){  if(zfname[i].endsWith(″.zip")){  try{  loadPackage(newFile(dir,zfname[i]));  }catch(ZipExceptionze){Filef=newFile(dir,zfname[i]);  f.delete();  }  }  }  }  dir=SmartLauncher.getSharedDir();  zfname=dir.list();  if(zfname!=null){  for(inti=0;i<zfname.length;i++){  if(zfname[i].endsWith(″.zip″)){  try{  loadPackage(newFile(dir,zfname[i]));  }catch(ZipExceptionze){  Filef=newFile(dir,zfname[i]);  f.delete();  }  }  }  }}publicvoidloadPackage(FilefZipFile)throwsIOException{  ZipFilezf=newZipFile(fZipFile);  ArchiveInfoai=newArchiveInfo(zf);  //装入该类。  for(Enumeratione=zf.entries();e.hasMoreElements();){  ZipEntryze=(ZipEntry)e.nextElement();  StringzipName=ze.getName();  if(zipName.endsWith(″.class″)){  StringclassName=getClassNameFromZipName(zipName);  m_lassMap.put(className,ai);  m_packageMap.put(getPackageName(className),ai);  }else{  zipName=zipName.replace(′\\′,′/′);  m_resourceMap.put(zipName,ai);  }  }}//装入一个包含在Ze.中的类。privateClassloadClassFromZipEntry(ZipFilezf,ZipEntryze,StringclassName)throwsIOException{  StringszZipName=ze.getName();  InputStreamis=zf.getInputStream(ze);  ByteArrayOutputStreambaos=newByteArrayOutputStream();byte[]tempBuf=newbyte;  intbytesRead=0;try{  do{  bytesRead=is.read(tempBuf,0,1024);  if(bytesRead>0){  baos.write(tempBuf,0,bytesRead);  }  }while(bytesRead>=0);  }catch(EOFExceptioneofex){  //Thisisfine.  }is.close();byte[]clsData=baos.toByteArray();returndefineClass(className,clsData,0,clsData.length);}privateStringgetClassNameFromZipName(StringzipName){intindex=zipName.lastIndexOf(″.class″);if(index<=0)  returnnull;StringclassName=zipName.replace(′/′.′);className=className.replace(′\\′,′.′);returnclassName.substring(0,index);}/**//返回一个类的包名*/privateStringgetPackageName(StringclassName){intindex=className.lastIndexOf(".″);if(index<=0)  return″″;returnclassName.substring(0,index);}privateStringgetBaseclassName(Stringname){intiBegin=Math.max(0,name.lastIndexOf(″.″));intiEnd=name.indexOf(″_″,iBegin);if(iEnd==-1){  returnname;}]]></pre>图11示出了了流程图250,显示了按照本发明的一个实例,用于监测一个可执行程序的类的安装的方法,以便为程序的各特定功能生成模块。流程图250由操作252开始,此时,接收到一个运行该可执行程序的命令。接着,在操作254,产生对一个类的请求。在一个例子中,Java虚拟机请求该类。应该理解,一旦该可执行程序启动,则一组类,即一个核心模块,使得该程序能够被执行,因此,用户马上就可以使用该核心模块所提供的功能。如以上所提到的,一旦启动该程序,核心模块就包含具有入口点的主类。该方法接着执行操作256,监测类装入程序。在一个实例中,通过编写另一个类装入程序取代Java默认类装入程序(该另一个类装入程序是对该Java类装入程序的扩展),来监测该类装入程序。随后,在操作258,加载所请求的类。在一个实例中,从一个文件系统加载所请求的类。随后,进行操作260,记录所装入的类。应该理解,类是被记录在一个集合或矢量中的,因此,包含在一个模块中的所有相关类都被记录下来。因此,操作260开始定义组成核心模块的类或组成与非核心模块相关的模块的类。如此处所提到的,一个非核心模块是一个包含与该程序的一个特定功能或任务相联系的类的模块,而核心模块包含的是运行该应用程序所必需的类。图11的方法接着进行操作262,此时,该类被返回Java虚拟机。在一个实例中,若返回给Java虚拟机的类与另一个类相关联,则Java虚拟机将请求该相关联的类,并重复操作254-262。例如,若刚刚下载的类A与类B相关联,则Java虚拟机将请求类B。在操作260中记录类B,并在该应用程序运行期间建立相关联类的模型。应该理解,一个类可以与不止一个其它类相关联。沿着这条线索,若类B与类C和类J相关联,则Java虚拟机将请求类C和类J。因此,在应用程序运行期间,快速地为每个模块生成类图。监测应用程序装入过程的逻辑能检测一个终点,该终点表明一个特定模块的所有类都已下载完毕。一旦到达终点,其中记录了类的集合或矢量就完成了。即,一旦该模块的最后一个类被装入,则该模块的类图就完成了。在一个实例中,类图被存入一个联网资源服务器。接着,为下一个模块重复图11的方法,直到所有的模块(代表该应用程序的所有特定功能或任务)都已被装入。如以上所讨论的,每个特定功能和任务都可按用户的需要下载,和一个预测下载或按顺序的后台下载一样。应该理解,一旦装入了核心模块,则该应用程序就可以开始运行,因此,用户可以执行该核心模块提供的功能。图12A示出了了一个框图,举例说明了按照本发明的一个实例,构成一个应用程序的模块的类的列表。模块1264包括类A,B,C,F,J和H,而模块2266包括类D,E和G。在一个实例中,模块1264可以代表一个应用程序的核心模块,而模块2266代表一些特定功能。在前面提到的贺卡例子中,核心模块264包含运行贺卡应用程序引擎所必需的所有类,模块2266包含一个特定功能或任务必需的类,该特定功能或任务可以是打印,编辑,旋转,插入文本等。在图12B中,只显示了两个模块,事实上,该应用程序可以被细分为任意数量的模块。图12B示出了了按本发明的一个实例,图12A的模块1264的示出了类图。如图12B所表示的,类A268与类B270相关,类B270叉与类C272和类J278相关,以此类推。在一个实例中,一旦模块1264的所有类都已装入并记录,则生成一个类图,该类图的形式为联网资源服务器上的一个映象。在监测工具对应用程序进行监测和记录的同时,随着该应用程序每项特定功能的执行,快速生成该映象。在一个实例中,所记录的模块被存储在与服务器通信的一个存储介质上。随后,服务器察看每个文件并创建一个数据库,即一个映象。在一个推荐实例中,模块被存储为zip文件,每个模块都与一个zip文件相关。服务器察看每个zip文件并创建一个数据结构。其结果是,在程序运行期间为每个模块生成一个类图,而不是进行手工分析代码这项繁琐的劳动。随后,在下载该应用程序时使用该类图,如参照图7-10所描述的那样。在一个实例中,模块可以包含类,图像,文本文件,类所要求的代码(例如动态链接库(DLLs)),字符串资源或其它能够呈现类所需要的特性的资源。图13示出了了按照本发明的一个实例,在一个应用程序运行时监测程序的部分输出的例子。如图13所显示的,在装入多个类时将它们记录下来。应该理解,除了类文件之外,在模块中还可包含图形互换格式(GIF)文件。GIF文件用于显示应用程序的各种图形图像,不过,在另一个实例中,可以利用联合摄影专家组(JPEG),带标志图像文件格式(TIFF)等代替GIF文件格式。对于该应用程序的每个特性,重复图13中所显示的示出了输出。若在图13中,应用程序刚刚开始,则监测程序将捕捉核心模块。随着该应用程序每项特定功能的使用,创建一个模块,并且对于每一个模块,都生成类似于图13的一个输出。图14示出了了按照本发明的一个实例,监测程序从一个贺卡应用程序捕捉的核心模块的示出了类的部分输出和GIF文件。如图14所示出了的,一些文件包含在这一应用程序的核心模块中。沿着这些线索,可以充分意识到手工分析一个应用程序的代码,以确定该应用程序的类之间的相互关系所需要的庞大的工作量。尽管在图13和14中提供了监测工具输出的例子,但这并不意味着限定本发明。应该理解到,贺卡应用程序只是起举例的作用,该应用程序可以是任何能由一个或多个处理实体执行的任意类型的应用程序。监测并记录了该应用程序使用的所有特定功能之后,有可能一个或多个类是多个模块公用的。在一个实例中,重复的类被放置在一个模块中,并为其余模块提供到包含所需类的模块的链接。在另一个实例中,重复的类被包含在核心模块中,这是因为核心模块总是第一个被下载,因此,总是可以使用这些公用类。在另一个实例中,公用的类被移入一个公用的模块中,需要该公用模块中的类的模块可以访问该模块。在如何构造任何可以下载的应用程序的模块,以便通过诸如因特网之类的分布式网络有效地下载该应用程序这一方面,本发明实例允许留有多余的可能性。尽管在以上描述本发明时,结合的是一个在一个与个人电脑相结合的操作系统上运行的应用程序,但应该理解,本发明可以由其它例程,程序,组件,数据结构等(它们执行特定的任务或实现特定的抽象数据类型)实现。另外,本发明可用于其它的计算机系统结构,该系统可以包括手持设备,微处理器系统,基于微处理器或可编程的用户电子设备,微计算机,主计算机等。本发明还可用于分布式计算系统,其中,任务是通过远程处理设备执行的,远程处理设备通过一个通信网络连接。考虑到以上的实例,应该理解,本发明可使用各种计算机实现的操作,这些操作涉及存储在计算机系统中的数据。这些操作是那些请求物理实体的物理控制的操作。通常,尽管不是必需的,这些实体的形式采用的是电或磁信号,能够被存储,变换,组合,比较,或其它方面的控制。另外,所执行的控制一般指的是,例如,生成,识别,判断或比较。此处所描述的任何构成本发明一部分的操作都是有用的机器操作。本发明还与一个用于执行这些操作的设备或装置相关,该装置可以是为所需目的专门构造的,或者,它可以是一个通用计算机,由存储在其中的一个计算机程序有选择地触发或设定。具体的,可以使用任何带有按本发明技术编写的计算机程序的通用机器,或者,可以更方便地构造一个更专用的设备来执行所要求的操作。本发明还可体现为一个计算机可读介质上的计算机可读代码。该计算机可读介质是能存储随后由一个计算机系统读取的数据的任意数据存储设备。该计算机可读介质的例子包括硬磁盘机,网络附属存储器(NAS),只读存储器,随机存取存储器,CD-ROM,CD-R,CD-RW,磁带和其它光学或非光学数据存储设备。该计算机可读介质还可分布在一个与计算机系统相连的网络上,从而,可以分布式的方式存储并执行该计算机可读代码。尽管以上为了便于理解,已详细介绍了本发明,但应该理解,在附加权利要求的范围内,可以对以上所描述的方法进行某些修改。如以上所提到的,尽管在一些实例中参照一个打印机应用程序的例子讨论了应用程序,但该应用程序可以是任意类型的能由一个或多个处理实体处理的应用程序。因此,本发明的实例起的是举例说明的作用,并不限定本发明的范围,本发明并不局限于此处给出的细节,在附加权利要求的范围和等价形式之内可以对本发明进行修改。权利要求1.一种计算机实现的方法,用于识别一个可执行程序的模块,该方法包括启动该可执行程序;在该可执行程序执行期间,监测该可执行程序,该监测包括识别每个模块的相互关联类,每个模块都对应于该可执行程序的一个特定功能;在该可执行程序执行期间为每个模块生成一个数据结构,该数据结构定义每个特定功能的类。2.权利要求1中所陈述的方法,其中,这些模块之一是一个核心模块。3.权利要求1中所陈述的方法,其中监测可执行程序的步骤还包括在一个集合中记录相互关联的类;并存储该数据结构。4.权利要求3中所陈述的方法,其中该数据结构被存储在一个联网资源服务器上。5.权利要求1中所陈述的方法,其中监测可执行程序的步骤还包括将两个或多个模块公用的类组合在一个独立模块中。6.一种生成类图的方法,该类图表明一个可执行程序的模块怎样使用该可执行程序的类,该方法包括在该可执行程序执行期间监测该可执行程序;识别与一个核心模块相联系的每个类,该核心模块用来运行该程序的引擎;在该程序被监测的同时执行与该程序有关的每项任务;执行每项任务执行时用到的每个类;为核心模块和每项任务定义一个类图,其中,每个类图都定义核心模块和每项任务中类的相互作用。7.权利要求6中所陈述的方法,其中执行每项任务还包括请求与每项任务相关的每个类。8.权利要求7中所陈述的方法,其中从一个文件系统中装入所请求的类。9.权利要求6中所陈述的方法,其中该可执行程序是一个打印应用程序。10.一种方法,用于将一个可执行程序细分为自主类模块,其中,每个模块对应于一项任务,该方法包括执行该程序;监测该程序的执行;保留每项任务执行期间使用的类的记录;为每个模块定义一个类图,该类图表示与每个模块相关的类的相互作用。11.权利要求10中所陈述的方法,其中保留一个类的记录还包括通过一个类装入程序装入该类;记录所装入的类;向一个Java虚拟机返回该类。12.权利要求11中所陈述的方法,还包括检测一个终点,该终点表明每个模块的所有类都已装入完毕。13.权利要求10中所陈述的方法,其中这些模块之一是一个运行该可执行程序的引擎的核心模块。14.权利要求10中所陈述的方法,其中每项任务的类的记录被保存为一个zip文件。15.权利要求10中所陈述的方法,其中每个模块都与一个zip文件相关。16.权利要求13中所陈述的方法,其中保留每项任务执行期间用到的类的记录的步骤还包括识别多个模块公用的类;和将识别出的多个模块公用的类放在核心模块中。17.为一个应用程序开发一个软件产品的方法,该应用程序具有多项特定功能,其中每项特定功能都与至少一个类相关,该方法包括识别该应用程序的每个类;执行该应用程序的每项特定功能;识别与每项特定功能相关的每个类;为每项特定功能定义一个模块,每个模块都包含所识别出的与某特定功能相关的一组类,其中每个模块都能使与该模块相对应的功能得以完成。18.权利要求17中所陈述的方法,其中一个模块是一个核心模块,包含带有该应用程序入口点的主类。19.权利要求17中所陈述的方法,其中为每个特定功能定义一个模块的步骤还包括将该模块的每个类存入一个集合。20.权利要求19中所陈述的方法,其中该模块被存储为一个联网资源服务器上的一个zip文件,根据来自一个Java虚拟机请求,通过一个网络下载该zip文件。21.权利要求20中所陈述的方法,其中通过网络的下载是由来自用户的一个要求,一个预测下载和一个按顺序的后台下载启动的。22.一种用于生成一个应用程序的一个模块的方法,该模块能自主运行该应用程序的一个特定功能,该方法包括启动该应用程序;请求一个类装入程序装入一个类;在装入该模块的每个类时,对该类装入程序进行监测;记录该模块的每个类;检测一个终点,该终点表明该模块的所有类都已下载完毕。对于该应用程序的其余模块,重复该请求,监测,记录和检测步骤。23.权利要求22中所陈述的方法,其中一个Java虚拟机请求该类装入程序。24.权利要求22中所陈述的方法,其中该模块的每个类都被记录在一个集合和一个矢量之一中。25.权利要求22中所陈述的方法,还包括将所记录的类返回给一个Java虚拟机。26.权利要求22中所陈述的方法,其中该应用程序提供一个打印机的功能。27.一个带有用来生成类图的程序指令的计算机可读介质,该类图表明一个可执行程序的模块怎样使用该可执行程序的类,该计算机可读介质包括用于在该可执行程序运行时监测该程序的程序指令;用于识别与一个核心模块相关的每个类的程序指令,该核心模块运行该程序的一个引擎;用于在监测该程序的同时,执行与该程序相关的每项任务的程序指令;用于记录每项任务执行时用到的每个类的程序指令;用于为核心模块和每项任务定义一个类图的程序指令,其中每个类图都定义核心模块和每项任务中类的相互作用。28.权利要求27中所陈述的计算机可读介质,其中用于记录每个类的程序指令还包括用于检测一个终点的程序指令,该终点表明该核心模块的所有类都已装入完毕。29.权利要求27中所陈述的计算机可读介质,还包括用于识别与一个非核心模块相关的类的程序指令,该非核心模块使用户能够使用该应用程序的一项特定功能。30.权利要求29中所陈述的计算机可读介质,其中核心模块和非核心模块是经一个分布式网络下载的。全文摘要此处为一个软件工具提供了方法和计算机可读介质,该软件工具用于将程序细分为自主模块,其中这些模块能使该程序的特定功能得以完成。一个示出了方法包括一个计算机实现的方法,用于识别一个可执行程序的模块。该方法首先启动读可执行程序。随后,在该程序运行期间对其进行监测。对该可执行程序的监测还包括,为每个模块识别相关的类,其中,每个模块对应于该可执行程序的特定功能。文档编号G06F11/36GK1416058SQ0214815公开日2003年5月7日申请日期2002年10月31日优先权日2001年10月31日发明者李家欣,B·陈申请人:精工爱普生株式会社
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1