abstract:本文截取IBM 红皮书《WebSphere Application Server V6.1:系统管理与配置》的第 12 章节内容,详细阐述了类加载器的基本概念和使用,以及如何客户化类加载器,通过例子阐述了影响类加载的选项的使用。 keywords:WebSphere Application Server ,类加载器 常常有客户询问我,WAS 中的类加载策略怎么理解。这不是一句话能够说清楚的。所以截取了IBM 红皮书《WebSphere Application Server V6.1:系统管理与配置》的第 12 章节,详细阐述了类加载器的基本概念和使用,以及如何客户化类加载器。 理解Java以及Websphere的类加载策略对打包和部署J2EE程序至关重要。当启动应用程序时,如果类加载失败,就会出现类加载的异常,比如ClassNotFoundException。本文解释了类加载以及为了应用程序的需要如何客户化Websphere 类加载。 后简称WebSphere Application Server V6.1 为WAS 6.1 12.1 Java类加载器介绍 类加载器负责把类加载到Java虚拟机(JVM)中。指定类的名称,类加载器就会定位这个类的定义,每一个Java类必须由类加载器加载。 当启动JVM的时候,可以使用三个类加载器:引导(bootstrap)类加载器、扩展(extensions)类加载器、应用程序(application)类加载器。 1.引导类加载器仅仅负责加载核心的Java库,比如位于<JAVA_HOME>/jre/lib 目录下的vm.jar,core.jar。这个类加载器,是JVM核心部分,是用native代码写成的。 2.扩展类加载器负责加载扩展路径下的代码,一般位于<JAVA_HOME>/jre/lib/ext 或者通过java.ext.dirs 这个系统属性指定的路径下的代码。这个类加载器是由sun.misc.Launcher$ExtClassLoader 实现的。 3.应用程序类加载器负责加载java.class.path(映射系统参数 CLASSPATH的值) 路径下面的代码,这个类加载器是由 sun.misc.Launcher$AppClassLoader 实现的。 当处理类加载器时,父委托模式是一个需要理解的关键概念。它规定:类加载器在加载自己的类之前,可以委托先加载父类。父类加载器可以是客户化的类加载器或者引导类加载器。但是有一点很重要,类加载器只能委托自己的父类加载器,而不能是子类加载器(只能向上不能向下)。 扩展类加载器是应用程序类加载器的父亲。类加载器的层次图见图12-1 。 图12-1 类加载器层次图 如果应用程序类加载器需要加载一个类,它首先委托扩展类加载器,扩展类加载器再委托引导类加载器。如果父类加载器不能加载类,子类加载器就回在自己的库中查找这个类。基于这个特性,类加载器只负责它的祖先无法加载的类。 如果类加载器加载一个类,这个类不是在类加载器树上的叶子节点上,就会出现一些有趣的问题。比如例12-1,一个名为WhichClassLoader1 的类加载了一个名为WhichClassLoader2类,WhichClassLoader2又调用了名为WhichClassLoader3的类。 例12-1 WhichClassLoader1 和 WhichClassLoader2 源代码 public class WhichClassLoader1 { public static void main(String[] args) throws javax.naming.NamingException { // Get classpath values String bootClassPath = System.getProperty("sun.boot.class.path"); String extClassPath = System.getProperty("java.ext.dirs"); String appClassPath = System.getProperty("java.class.path"); // Print them out System.out.println("Bootstrap classpath =" + bootClassPath + "\n"); System.out.println("Extensions classpath =" + extClassPath + "\n"); System.out.println("Application classpath=" + appClassPath + "\n"); // Load classes Object bj = new Object(); WhichClassLoader1 wcl1 = new WhichClassLoader1(); WhichClassLoader2 wcl2 = new WhichClassLoader2(); // Who loaded what? System.out.println("Object was loaded by " + obj.getClass().getClassLoader()); System.out.println("WCL1 was loaded by " + wcl1.getClass().getClassLoader()); System.out.println("WCL2 was loaded by " + wcl2.getClass().getClassLoader()); wcl2.getTheClass(); } } ====================================================================== public class WhichClassLoader2 { // This method is invoked from WhichClassLoader1 public void getTheClass() { WhichClassLoader3 wcl3 = new WhichClassLoader3(); System.out.println("WCL3 was loaded by " + wcl3.getClass().getClassLoader()); } } 如果所有的WhichClassLoaderX 类都放在应用程序的类路径下,三个类就会被应用程序类加载器加载,这个例子就会运行正常。现在假定把WhichClassLoader2 类文件打包成JAR文件放在<JAVA_HOME>/jre/lib/ext 目录下,运行WhichClassLoader1,就会看到例12-2的输出: 例12-2 NoClassDefFoundError 异常跟踪 Bootstrap classpath =C:\WebSphere\AppServer\java\jre\lib\vm.jar;C:\WebSphere\AppServer\java\jre\lib \core.jar;C:\WebSphere\AppServer\java\jre\lib\charsets.jar;C:\WebSphere\AppServ er\java\jre\lib\graphics.jar;C:\WebSphere\AppServer\java\jre\lib\security.jar;C :\WebSphere\AppServer\java\jre\lib\ibmpkcs.jar;C:\WebSphere\AppServer\java\jre\ lib\ibmorb.jar;C:\WebSphere\AppServer\java\jre\lib\ibmcfw.jar;C:\WebSphere\AppS erver\java\jre\lib\ibmorbapi.jar;C:\WebSphere\AppServer\java\jre\lib\ibmjcefw.j ar;C:\WebSphere\AppServer\java\jre\lib\ibmjgssprovider.jar;C:\WebSphere\AppServ er\java\jre\lib\ibmjsseprovider2.jar;C:\WebSphere\AppServer\java\jre\lib\ibmjaa slm.jar;C:\WebSphere\AppServer\java\jre\lib\ibmjaasactivelm.jar;C:\WebSphere\Ap pServer\java\jre\lib\ibmcertpathprovider.jar;C:\WebSphere\AppServer\java\jre\li b\server.jar;C:\WebSphere\AppServer\java\jre\lib\xml.jar Extensions classpath =C:\WebSphere\AppServer\java\jre\lib\ext Application classpath=. Exception in thread "main" java.lang.NoClassDefFoundError: WhichClassLoader3 at java.lang.J9VMInternals.verifyImpl(Native Method) at java.lang.J9VMInternals.verify(J9VMInternals.java:59) at java.lang.J9VMInternals.initialize(J9VMInternals.java:120) at WhichClassLoader1.main(WhichClassLoader1.java:17) 正如所看到的,由于WhichClassLoader3 在应用程序类路径下,程序失败,收到一个NoClassDefFoundError 的异常,这看起来有些奇怪。问题在于:它现在在一个错误的类路径下面。当WhichClassLoader2被扩展类加载器加载的时候,发生了什么呢?实际上,应用程序类加载器委托扩展类加载器加载WhichClassLoader2,扩展类加载器又委托引导类加载器。由于引导类加载器找不到这个类,类加载的控制就会返回给扩展类加载器。扩展类加载器在自己的路径下找到了这个类将它加载。现在,当一个类已经被类加载器加载后,这个类需要的任何其他的新类都必须用同一个类加载器加载他们(或者遵循父委托模式,由父类加载器加载)。所以当WhichClassLoader2 需要访问WhichClassLoader3 的时候,扩展类加载器就会获得这个请求去加载WhichClassLoader3,扩展类加载器先委托引导类加载器,但是引导类加载器找不到这个类,于是扩展类加载器便试图装入自身但是也找不到这个类,原因是WhichClassLoader3不在扩展类路径而是在应用程序类路径。由于扩展类加载器无法委托应用程序类加载器,所以就会出现NoClassDefFoundError 的异常。 注意:开发者通常会使用如下语法通过类加载器机制加载属性文件: Properties p = new Properties(); p.load(MyClass.class.getClassLoader().getResourceAsStream("myApp.properties" )); 这个意思是:如果MyClass 由扩展类加载器加载,而 myApp.properties 文件只能应用程序类加载器看到,则装入属性文件就会失败。
发表评论
-
控制台SESSIONOUT
2010-09-17 13:04 1137通过配置文件来修改WAS控制台Session过期时间的方法 ... -
SOCKET 异常类型
2010-03-30 16:42 1741Error code Meaning ... -
Transaction Introduce
2010-03-30 14:01 1120Transaction 什么是Transaction? ... -
DB2 死锁
2010-03-26 10:33 4220解决“SQL0911N 因为死锁 ... -
WAS 事物引起的错误
2010-03-25 17:13 2465一、性能故障的现 ... -
案例分析
2010-03-16 16:53 1585系统上线后偶有宕机, ... -
Remote Rendering portlet hangs on socketRead0()
2010-03-16 16:46 1937当我们在JAVACORE文件中发现很多WEBCONTAINER ... -
WAS Portal Theme Development And Configuration
2010-03-12 22:37 1300我们先介绍一下主题和 ... -
Portal 主题部署
2010-03-12 22:21 1373部署定制的主题和外 ... -
应用服务器出现错误的原因简析
2010-03-11 22:19 873磁盘已满 导致 ... -
WAS 中Too many open files问题
2010-03-11 22:16 1258WAS下的应用系统,在对其他性能开至较大时出现系统无法返回的情 ... -
急性者的性能优化
2010-03-05 11:02 880引言 如果您是这样一个人:启动并运行 WebSphere ... -
控制台安全性破解
2010-03-04 23:05 949常在河边走,哪有不湿鞋,WebSphere管理中最让人 ... -
查看WAS版本
2010-03-04 22:39 2617一、查看WAS版本的方式:1、命令行 cd $WAS_HOM ... -
WAS设置编码方式
2010-03-04 22:29 4371当安装了webSphere的小型机的默认编码不是GBK ... -
WAS 6.1 的类加载四
2010-03-04 12:35 109212.5.2 步骤 2:添加一个EJB模块和工具JAR ... -
WAS的类加载机制三
2010-03-04 12:34 141712.3.1 类加载策略 ... -
WAS的类加载机制二
2010-03-04 12:33 90412.2 概览Websphere 类加载器 注意:每一个 ...
相关推荐
3. **类加载机制**:理解并调整类加载器的设置,可以避免类装载冲突和内存泄漏。 接下来,我们关注线程配置: 1. **线程池大小**:线程数的设置应基于应用的并发需求,过多的线程可能导致内存浪费,过少则可能导致...
WAS 中类加载器是一个具有父子关系的分层结构,包括 JVM Class loader、WebSphere Extensions Class loader、WebSphere lib/app Class loader、WebSphere "server" Class loader 和 Application Module Class Loader...
这种机制确保了类的唯一性,即相同的类只会被同一个类装载器加载一次。同时,这也使得类之间的隔离变得可能,即使两个类具有相同的全限定名,只要它们由不同的类装载器加载,就可以视为不同的类。 #### WebSphere类...
在 WebSphere 中,类加载器的层次结构是一个自上而下的分层结构,最上层是系统的运行环境 JVM,最下层是具体的应用程序,上下层之间形成父子关系。这个层次结构中包括以下几个部分: * JVM Class loader:位于整个...
3. **类加载与卸载**:通过调整类加载机制减少不必要的类加载和卸载,如使用-XX:MaxMetaspaceSize=256m 来控制元空间大小。 4. **JIT编译**:JIT编译器可以将热点代码编译为机器码,从而提高执行效率。可以通过-XX:...
这一机制确保了类的单一性,避免了类加载冲突。 #### WebSphere类装入器概述 WebSphere Application Server (WAS) 在Java的类装入器基础上进行了扩展,以适应企业级应用的需求。WebSphere支持多种类装入器,包括但...
- **类加载器** - **可插拔组件** - **线程模型** - **JVM 分析工具** - **调试器** - **实时分析工具** #### WAS 所使用的不同 JVM WAS 可以支持多种 JVM,包括 IBM 自家的 JVM 以及 Sun HotSpot 基础的 JVM。具体...
为了缓解这一问题,建议对业务逻辑进行重构,实施有效的分页机制,避免一次性加载过多数据。 通过以上分析可以看出,本次事件是由多方面因素共同作用的结果。除了针对特定的技术问题进行修复外,还需要从整体架构的...
3. **配置文件问题**:Tomcat的主配置文件如`server.xml`或`context.xml`可能存在错误,如XML格式错误、端口冲突或者类加载器配置不当等。 4. **内存不足**:如果服务器的内存资源不足,Tomcat可能无法启动。检查并...
- WebSphere Application Server (WAS) 是IBM提供的一个基于Java EE(现在称为Jakarta EE)标准的应用服务器,用于运行和管理分布式应用程序。 - WAS支持各种服务,包括Servlet、JSP、EJB、JMS、JTA、JNDI等,为...
- 这一步骤可以帮助清除已编译的类文件和其他临时文件,有时能够解决问题。 4. **禁用或卸载第三方插件**: - 检查是否安装了可能引起冲突的第三方插件。 - 尝试禁用或卸载这些插件后重新构建项目。 5. **重置...
配置应用程序的上下文根、类加载器策略和资源引用。 4. **安全管理**: 配置用户认证和授权,可以使用基本认证、LTPA( Lightweight Third-Party Authentication)或其他安全认证机制。同时,设置角色和权限,将用户...
WebSphere Application Server(WAS)6版本提供了丰富的调优工具和技术,帮助管理员优化应用服务器性能,确保应用程序高效运行。该版本引入了多项改进,旨在简化性能调优过程,并提升系统整体响应速度。 1. **调优...
- **Struts2错误处理与自动加载web.xml**:WebSphere下部署Struts2应用时,可能遇到错误处理机制失效或web.xml修改后未生效的问题。确保应用重启策略正确,以及JSP预编译等设置符合需求。 以上是基于给定文件的...