一种类装载隔离的方法及一种类装载隔离的装置的制作方法

文档序号:6611959阅读:117来源:国知局
专利名称:一种类装载隔离的方法及一种类装载隔离的装置的制作方法
技术领域
本发明涉及Java的类装载隔离领域,特别涉及一种基于Java虚拟机 的类装载隔离的方法及一种类装载隔离的装置。
背景技术
目前在Internet/Intranet/Extranet环境中,企业级应用系统大多采用三 层或多层应用模式。为了方便开发、部署、运行和管理基于多层结构的 应用,需要以网络和分布式计算的底层技术为基础,构建一个完整的应 用框架,提供相应的支撑平台作为多层应用的基础设施,这一支撑平台 的关键就是位于中间层的应用服务器。应用服务器是一个创建、部署、 运行、集成和维护多层分布式企业级应用的平台。在企业应用中,应用 服务器可以提供如下好处(1 )提高企业应用开发的有效性,保障业务逻 辑和组件的重用性;(2)提高企业应用的性能,比如,高运行性能和响 应时间、可伸缩性、可靠性等;(3)使企业应用更易于监控和管理,降 低系统维护和升级成本。由于应用服务器的重要作用和关键地位,它已 经成为当今业界的一个热点。
从某种角度而言,应用服务器本身是一个Java进程,而类装载是Java 语言提供的最强大的机制之一。具体而言, 一个类代表要执行的代码, 而数据则表示其相关状态,状态时常改变,而代码则不会。将一个特定 的状态与一个类相对应起来,也就意味着将一个类实例化;尽管相同的 类对应的实例其状态千差万别,但其本质都对应着同一段代码。应用服 务器自身的启动需要装载很多类文件,部署在应用服务器上的应用启动 时也需要装载应用自身的类文件,Java的类装载模型是一种代理 (delegation)模型。当Java虚拟机(Java Virtual Machine, JVM )要求类装 载器(ClassLoader)装载一个类时,类装载器首先将这个类装载请求转发 给他的父装载器,而父装载器会依次逐级向上传递请求,直到类装载层 次的顶部。如果顶部的类装载器不能完成类装载请求,它的子装载器将
被调用来完成类装载。如果子装载器也不能装载类,请求会继续向下传 递,直到一个类装载器完成这个请求。
通常情况下,应用服务器自身所需的类文件是在系统类路径中,部 署在应用服务器应用所需的类文件将会出现在系统类路径之后,因此, 如果应用服务器中和部署在应用服务器的应用中包含了相同命名空间的 类文件,那么包含在应用服务器中的类文件将会被先加载,包含在应用 中的类文件将无法被加载,如图1所示,假设应用服务器所需的类文件
存在于System Class Loader,应用所需的类文件存在于应用的Class Loader中,应用服务器和应用均具有相同命名空间的类文件A,当应用 需要装载这个类文件A时,按照Java的类装载模型,如果这个类文件亦 存在于应用的Class Loader的父装载器System Class Loader中,则会乂人 System Class Loader装载所述类文件A,而不会/人应用的Class Loader中 去装载。假设应用的Class Loader中的类文件A是较高版本的类文件, 而System Class Loader中的类文件A是较低版本的类文件,当前应用所 需要加载的类文件实际上应当为应用的Class Loader中的较高版本的类 文件A,然而,由于已装载了 System Class Loader中的类文件A,则应用 的Class Loader中的类文件A将无法被装载,从而导致系统出错,引发 例如"类找不到"、"类未被定义"等类沖突问题。
现有技术中,只能通过由开发或维护人员手动删除发生具有相同命 名空间的两个类文件其中的一个;或者,将所有需要加载的类文件都放 在系统的类路径中,并手动调整顺序来避免这种类冲突问题。显然,这 种手动处理方式的成本高,效率低,并且处理过程较为复杂。
因此,本领域技术人员迫切需要发展出一种可以简单、高效地解决 类冲突的方法及系统。

发明内容
本发明所要解决的技术问题是提供一种类装载隔离的方法,用以解 决现有技术中对于类沖突处理成本高、效率低,并且处理过程复杂的问 题。
本发明还提供了 一种类装载隔离的装置,用以保证上述方法在实际 中的实现及应用。
为解决上述技术问题,本发明实施例公开了 一种类装载隔离的方法,
包括
启动Java进程,在所述Java进程中创建自定义类装栽器对象; 在所述自定义类装载器对象中添加类路径;
创建启动应用服务器线程对象,并为所述线程对象指定所述自定义 类装载器对象;
启动所述应用服务器线程对象。
优选的是,所述的方法,还包括
在所述自定义类装载器对象中设置添加路径的行为。
优选的是,所述类路径添加步骤包括
调用所述添加路径的行为,将类路径添加至所述自定义类装栽器对 象中。
优选的是,通过以下步骤指定所述自定义类装载器
在所述启动应用服务器线程对象中执行设置类装载器的行为,导入 所述自定义类装载器对象。
优选的是,所述自定义类装载器对象和/或线程对象的创建为使用 Java语言的new关键字创建。
本发明实施例还公开了一种类装载隔离的装置,包括
Java启动单元,用于启动Java进禾呈;
类装载器创建单元,用于在所述Java进程中创建自定义类装载器对
象;
添加单元,用于在所述自定义类装载器对象中添加类路径; 线程创建单元,用于创建启动应用服务器线程对象; 指定单元,用于为所述线程对象指定所述自定义类装载器对象; 线程启动单元,用于启动所述应用服务器线程对象。 优选的是,所述的装置,还包括
行为设置单元,用于在所述自定义类装载器对象中设置添加路径的 行为。
优选的是,所述添加单元包括
调用子单元,用于调用所述添加路径的行为,将类路径添加至所述 自定义类装载器对象中。
优选的是,所述指定单元包括
导入子单元,用于在所述启动应用服务器线程对象中执行设置类装 载器的行为,导入所述自定义类装载器对象。 优选的是,所述的装置,还包括 运行单元,用于触发Java虚拟机运行。 与现有技术相比,本发明实施例具有以下优点
本发明通过使用自定义的类装载器隔离机制,灵活定制所需加载的 类路径及逻辑,从而将应用服务器所需要装载的类文件和部署在应用服 务器上的应用所需要装载的类文件隔离开来,提高了应用服务器的容错 性、增强了应用服务器的兼容性和稳定性。


图l是现有技术中一种类装载过程的示意图; 图2是本发明的 一种类装载隔离的方法实施例的流程图; 图3是应用本发明实施例后,部署在应用服务器上的应用装载类的 过程示意图4是应用本发明实施例后,部署在应用服务器的装载类的过程示 意图5是本发明的 一 种类装载隔离的装置实施例的结构框图; 图6是应用图5所示的优选实施例进行类装载隔离的流程图。
具体实施例方式
为使本发明的上述目的、特征和优点能够更加明显易懂,下面结合 附图和具体实施方式
对本发明作进一步详细的"^兌明。
本发明实施例的核心构思之一在于,通过使用自定义的类装载器隔 离机制,灵活定制所需加载的类路径及逻辑,从而将应用服务器所需要 装载的类文件和部署在应用服务器上的应用所需要装载的类文件进行隔
离,以提高应用服务器的容错性、增强应用服务器的兼容性和稳定性。 参照图2,示出了本发明的一种类装载隔离的方法实施例的流程图,
具体包括以下步骤
步骤201、启动Java进程,在所述Java进程中创建自定义类装载器 对象;
步骤202、在所述自定义类装载器对象中添加类路径; 步骤203、创建应用服务器启动线程对象,并为所述线程对象指定所 述自定义类装载器对象;
步骤204、启动所述应用服务器线程对象。
在运行Java程序时,首先需要运行Java虚拟机(JVM),再将包含 在类(.class)文件中的字节码装载到JVM中,这种装载是由类装载器
(ClassLoader)和它的子类来实现的。然而,类装载器并不是原封不动 地将类文件的字节码装载到JVM,而是将类文件中的内容转换成JVM使 用的类字节码。通过类装载器装载到JVM中的字节码数据,就成了可执 行的代码。JVM规范定义了两种类型的类装载器启动内装栽器(bootstrap) 和用户自定义装载器(user-defined class loader)。具体而言,JVM本身包含 了一个类装载器称为Bootstrap ClassLoader,和JVM —才羊,Bootstrap ClassLoader是用本地代码实现的,它负责加载核心Java Class,即所有 java,开头的类。另外JVM还会提供两个类装载器,它们都是用Java语 言编写的,由Bootstrap ClassLoader力口载;其中Extension ClassLoader负 责加载扩展的Java class,例如所有javax,开头的类和存放在JRE的ext
目录下的类,System ClassLoader是一个特殊的用户自定义类装载器,由 JVM的实现者提供,在编程者不特别指定装载器的情况下默认装载用户 类,它可以从java.class.path(CLASSPATH,环境变量)中装载代码,同时 还可以作为用户自定义类装载器的缺省父装载器。Java的类装载模型是 一种代理(delegation)模型。当JVM要求类装栽器装载一个类时,类装载 器首先将这个类装载请求转发给他的父装载器。只有当父装载器没有装 载并无法装载这个类时,类装载器才获得装载这个类的机会。这样,所 有类装载器的代理关系构成了一种树状的关系。树的根是类的Bootstrap ClassLoader,在JVM中它以"null"表示。除Bootstrap ClassLoader以外的 类装载器有且仅有一个父装载器。在创建一个装载器时,如果没有显式 地给出父装载器,那么JVM将默认系统装载器为其父装载器。
为了防止类冲突,则需要控制JVM中的类装载行为,在这种情况下, 可以编写自定义类装载器。需要说明的是,所述自定义类装载器需要继 承java.lang.ClassLoader或者它的子类。在实例化每个类装载器对象时, 需要指定 一 个父对象;如果没有指定的话,系统将自动指定 ClassLoader.getSystemClassLoader()为父对象;然后重写findClass()方法。 在实际中,本领域技术人员采用任一种自定义类装载器的实现方法都是 可4亍的,例如,通过以下代码
protected final Class defineClass(String name, byte data[〗,int offset, int length);
protected final Class defmeClass(String name, byte data[], int offset, int length, ProtectionDomain protectionDomain);
protected final Class findSystemClass(String name); 或protected final void resolveClass(Class c)等。
其中,defineClass用来将二进制class文件(新类型)导入到方法区, 也就是说,这里指的类是用户自定义的类,也就是负责装载类; findSystemClass通过类型的全限定名,先通过系统类装载器或者启动类 装载器来装载,并返回Class对象;ResolveClass:让类装载器进行连接动用。
当在Java进程中创建所述自定义类装载器对象时,可以采用Java语 言的new关键字或现有技术中的其它方法进行创建。可以理解, 一旦类 装载器对象被创建,则授权关系也以父子关系的形式亦被形成,即,在 这种情况下,某个类装载器可以将装载某个类的权利授权给另一个类装 载器。例如, 一种采用自定义类装载器装入类文件的代码如下所示 〃首先创建一个ClassLoader对象 ClassLoader myClassLoader = new myClassLoader();
〃利用定制ClassLoader对象装入类文件 〃并把它转换成Class对象
Class myClass = myClassLoader.loadClass( "mypackage.MyClass");
〃最后,创建该类的一个实例
Object newlnstance = myClass.newInstance();
在本例中,MyClass所需要的所有其它类,都将通过自定义类装载器 自动装入。
在实际中,类(.class文件)可以存在目录或jar文件中,或者存储 在两者的组合中,但是只有在它们位于类路径中的某个地方时,javac编 译器或解释器才可以找到它们。可以看出,类路径可以用于使Java解释 器和javac编译器知道去何处查找它们要执行或导入的类。优选的是,在 本实施例中,还可以包括步骤在创建所述自定义类装载器对象时,在 所述自定义类装载器对象中设置添加路径的行为,则相应地,所述类路 径的添加步骤则可以为调用所述添加路径的4亍为,将类^4圣添加至所 述自定义类装载器对象中。在本实施例中,添加路径这个行为的实现机 制是将所加入的资源路径逐个扫描,直至找到所需的类资源为止。
当然,本领域技术人员根据需要或经验采用其它的类路径设置方法 也是可行的,例如,永久地,通过在系统级上设置CLASSPATH环境变 量来实现;或者,临时地,通过在命令窗口或shell中设置CLASSPATH 环境变量来实现;或者,在运行时进行,每次启动Java应用程序和JVM 都要指定类路径等,本发明对此不需要进行限定。
为有效解决应用服务器和部署在应用服务器中的应用两者都装载了 相同命名空间的类而产生的问题,本实施例需要进一步编写应用服务器 启动线程,公知的是,线程与进程相似,是一段完成某个特定功能的代 码,是程序中单个顺序的流控制;但与进程不同的是,同类的多个线程 是共享一块内存空间和一组系统资源,而线程本身的数据通常只有微处 理器的寄存器数据,以及一个供程序执行时使用的堆栈。所以系统在产 生一个线程,或者在各个线程之间切换时,负担要比进程小的多,正因 如此,线程被称为轻负荷进程(light-weight process )。 一个进程中可以包
含多个线程。在Java中,线程由三部分组成(1)虚拟的cpu,封装在 java.lang.Thread类中;(2 ) CPU所执行的代码,传递给Thread类;(3) CPU所处理的数据,传递给Thread类。Java的线程是通过java.lang.Thread 类来实现的。当生成一个Thread类的对象之后, 一个新的线程就产生了。 根据上述特性,本领域技术人员采用任一种创建线程的方法都是可行的, 例如, 一种显式地创建一 个绑定于MyAsyncTask方法的ThreadStart委4乇 对象的方法为Dim ThreadB As New Thread(AddressOf TedsCode.MyAsyncTask),本发明对此不作限制。
在本实施例中,可以根据Java的线程机制编写一个线程,由于Java 中内建了对多线程应用程序的支持,每个线程都由java.lang.Thread类的 一个实例所表示,因此,要创建新的线程实例,则该线程需要继承自Java 语言中的java.lang.Thread类,然后将"调用应用服务器的启动"的行为放 在此线程的run()方法中。当这个线程启动时候,这个行为将会被触发。 在编写好所述应用服务器启动线程后,即可根据该应用服务器启动线程 创建应用服务器线程对象,直接使用Java语言的new关键字或其它方法, 即可创建这个线程对象。
然后,对这个线程对象指定其类装载器为所述自定义类装载器,优 选的是,在本实施例中可以通过以下步骤指定所述自定义类装载器
在所述启动应用服务器线程对象中执行设置类装载器的行为,导入 所述自定义类装载器对象。
Java语言本身为线程提供了设置线程的上下文类装载器的方法,在 本实施例中,使用创建的线程对象,让其执行"设置类装载器"这个行为, 并将之前设置的自定义类装载器对象导入,则这个线程对象的类装载器 已经被设置为自定义类装载器。
在完成上述操作后,即可启动线程,在实际中,启动线程的方法就 是通过Thread类的start()实例方法,即直接调用线程对象的start方法, 例如,采用下述代码
Thread t = new Thread();
t.start();
即可启动线程。由于start()方法是一个native (本地)方法,它将启 动一个新线程,并执4亍run()方法。因此,线程启动后,线程的 run方法 内的"应用服务器启动"逻辑即被执行。在这种情况下,应用服务器是在这 个"被设置过类装载器的线程,,中被执行的,所以在应用服务器中,默认的 类加载行为由所述自定义类装载器来执行。
通过上述步骤可以看出,在应用服务器环境下,本发明实施例装载 类的操作是使用的自定义的类装载器执行,装载每个类的逻辑也是由所 述自定义的类装载器控制,从而有效避免了类冲突出现的情形。
参考图3,示出了应用本发明实施例后,部署在应用服务器上的应用 装载类的过程示意图,可以包括以下步骤
步骤301、开始装载类;
步骤302、从Bootstrap ClassLoader中寻找要装载的类;
步骤303、判断是否在Bootstrap ClassLoader中找到要装载的类,如
果是,则装载该类;如果否,则执行下一步骤;
步骤304、从Extension ClassLoader中寻找要装载的类;
步骤305、判断是否在Extension ClassLoader中找到要装载的类,如
果是,则装载该类;如果否,则执行下一步骤;
步骤306、从System ClassLoader中寻找要装载的类;
在本步骤中,应用服务器所需要的类已经被隔离到自定义的类装载
器中,即在System ClassLoader中已没有应用服务器的类路径。
步骤307、判断是否在System ClassLoader中找到要装载的类,如果
是,则装载该类;如果否,则执行下一步骤;
步骤308、从应用的ClassLoader中寻找要装载的类;
步骤309、判断是否在应用的ClassLoader中找到要装载的类,如果
是,则装载该类;如果否,则执行步骤310; 步骤310、抛出异常给用户。
相应地,参考图4,示出了应用本发明实施例后,部署在应用服务器 的装载类的过程示意图,可以包括以下步骤
步骤401、开始装载类;
步骤402、从Bootstrap ClassLoader中寻找要装载的类;
步骤403、判断是否在Bootstrap ClassLoader中找到要装载的类,如
果是,则装载该类;如果否,则执行下一步骤;
步骤404、从Extension ClassLoader中寻找要装载的类;
步骤405、判断是否在Extension ClassLoader中找到要装载的类,如
果是,则装载该类;如果否,则执行下一步骤;
步骤406、从System ClassLoader中寻找要装载的类;
步骤407、判断是否在System ClassLoader中找到要装载的类,如果
是,则装载该类;如果否,则执行下一步骤;
步骤408、从Server ClassLoader中寻找要装载的类;
Server ClassLoader为自定义类装载器,即应用J5良务器使用自身的自
定义类装载器装载所需的类文件。
步骤409、判断是否在Server ClassLoader中找到要装载的类,如果
是,则装载该类;如果否,则执行步骤410; 步骤410、抛出异常给用户。
从以上图3和图4可以看出,应用服务器在装载自身所需要的类时, 是使用自身所带的Server ClassLoader,应用装载类时,也是使用自身的 ClassLoader,由于不同的类装载器之间是有一定隔离性的,被不同类装 载器后,彼此之间是可以没有关系的,从而保证了与应用装载的类不发 生冲突。因而本发明可以有效的解决在实际应用中,由于类冲突而产生 的"类找不到"、"类未被定义"等的问题。并且,通过使用自定义的 ClassLoader隔离机制,更灵活地定制所需加载的类路径和逻辑顺序。
参考图5,示出了本发明的一种类装载隔离的装置实施例的结构框 图,包括以下单元
Java启动单元501,用于启动Java进程;
类装载器创建单元502,用于在所述Java进程中创建自定义类装载 器对象;
添加单元503,用于在所述自定义类装载器对象中添加类路径; 线程创建单元504,用于创建启动应用月艮务器线程对象; 指定单元505,用于为所述线程对象指定所述自定义类装载器对象;
线程启动单元506,用于启动所述应用服务器线程对象。
优选的是,本实施例还可以包括行为设置单元,用于在所述自定义
类装载器对象中设置添加路径的行为。
优选的是,所述添加单元进一步包括调用子单元,用于调用所述添
加路径的行为,将类路径添加至所述自定义类装载器对象中。
优选的是,所述指定单元进一步包括导入子单元,用于在所述启动
应用服务器线程对象中执行设置类装载器的行为,导入所述自定义类装
载器对象。
优选的是,本实施例还可以包括运行单元,用于触发Java虚拟机运行。
参考图6,示出了应用图5所示的优选实施例进行类装载隔离的流程 图,具体包括以下步骤
步骤601 、运行单元触发Java虚拟机运行; 步骤602、 Java启动单元启动Java进程;
步骤603、类装载器创建单元在所述Java进程中创建自定义类装载 器对象;
步骤604、添加单元在所述自定义类装载器对象中添加类路径; 步骤605、线程创建单元创建启动应用服务器线程对象; 步骤606、指定单元为所述线程对象指定所述自定义类装载器对象; 步骤607、线程启动单元启动所述应用服务器线程对象。 对于装置实施例而言,由于其基本相应于方法实施例,所以描述的 比较简单,相关之处参见方法实施例的部分说明即可。
本发明可以用于众多通用或专用的计算系统环境或配置中。例如 个人计算机、服务器计算机、手持设备或便携式设备、平板型设备、多 处理器系统、基于微处理器的系统、置顶盒、可编程的消费电子设备、 网络PC、小型计算机、大型计算机、包括以上任何系统或设备的分布式 计算环境等等。此外,本发明还可以在由计算机执行的计算机可执行指 令的一般上下文中描述,例如程序模块。 一般地,程序模块包括执行特
定任务或实现特定抽象数据类型的例程、程序、对象、组件、数据结构 等等。也可以在分布式计算环境中实践本发明,在这些分布式计算环境 中,由通过通信网络而被连接的远程处理设备来执行任务。在分布式计
储介质中。
以上对本发明所提供的 一种类装载隔离的方法及一种类装载隔离的
式进行了阐述,以上实施例的说明只是用于帮助理解本发明的方法及其 核心思想;同时,对于本领域的一般技术人员,依据本发明的思想,在具体实施方式
及应用范围上均会有改变之处,综上所述,本说明书内容
不应理解为对本发明的限制。
权利要求
1、一种类装载隔离的方法,其特征在于,所述方法包括启动Java进程,在所述Java进程中创建自定义类装载器对象;在所述自定义类装载器对象中添加类路径;创建启动应用服务器线程对象,并为所述线程对象指定所述自定义类装载器对象;启动所述应用服务器线程对象。
2、 如权利要求l所述的方法,其特征在于,还包括 在所述自定义类装载器对象中设置添加路径的行为。
3、 如权利要求2所述的方法,其特征在于,所述类路径添加步骤包括调用所述添加路径的行为,将类路径添加至所述自定义类装载器对 象中。
4、 如权利要求1、 2或3所述的方法,其特征在于,通过以下步骤 指定所述自定义类装载器在所述启动应用服务器线程对象中执行设置类装载器的行为,导入 所述自定义类装载器对象。
5、 如权利要求l所述的方法,其特征在于,所述自定义类装载器对 象和/或线程对象的创建为使用Java语言的new关键字创建。
6、 一种类装载隔离的装置,其特征在于,包括 Java启动单元,用于启动Java进禾呈;类装载器创建单元,用于在所述Java进程中创建自定义类装载器对象;添加单元,用于在所述自定义类装载器对象中添加类路径;线程创建单元,用于创建启动应用服务器线程对象;指定单元,用于为所述线程对象指定所述自定义类装载器对象; 线程启动单元,用于启动所述应用服务器线程对象。
7、 如权利要求6所述的装置,其特征在于,还包括 行为设置单元,用于在所述自定义类装载器对象中设置添加路径的 行为。
8、 如权利要求7所述的装置,其特征在于,所述添加单元包括 调用子单元,用于调用所述添加路径的行为,将类路径添加至所述自定义类装载器对象中。
9、 如权利要求6、 7或8所述的装置,其特征在于,所述指定单元 包括导入子单元,用于在所述启动应用服务器线程对象中执行设置类装 载器的行为,导入所述自定义类装载器对象。
10、 如权利要求6所述的装置,其特征在于,还包括 运行单元,用于触发Java虚拟机运行。
全文摘要
本发明公开了一种类装载隔离的方法,所述方法包括启动Java进程,在所述Java进程中创建自定义类装载器对象;在所述自定义类装载器对象中添加类路径;创建启动应用服务器线程对象,并为所述线程对象指定所述自定义类装载器对象;以及,启动所述应用服务器线程对象。本发明通过使用自定义的类装载器隔离机制,灵活定制所需加载的类路径及逻辑,从而将应用服务器所需要装载的类文件和部署在应用服务器上的应用所需要装载的类文件隔离开来,提高了应用服务器的容错性、增强了应用服务器的兼容性和稳定性。
文档编号G06F9/445GK101105757SQ20071014763
公开日2008年1月16日 申请日期2007年8月31日 优先权日2007年8月31日
发明者旭 张 申请人:金蝶软件(中国)有限公司
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1