Jvm的类加载顺序
Bootstrap classloader
引导(原始)加载器,负责加载jvm核心类库
Extension classloader
扩展加载器,负责加载jre扩展目录(JAVA_HOME/jre/lib/ext或者由java.ext.dirs系统属性指定的)中JAR的类包。
System classloader
系统(应用)类加载器,它负责在JVM被启动时,加载来自在命令java中的-classpath或者java.class.path系统属性或者CLASSPATH操作系统属性所指定的JAR类包和类路径。
加载说明
classloader是有父子结构的,如system classloader的父亲是extension classloader,extension classloader的父亲bootstrap classloader,bootstrap classloader没有父亲,它是JVM一启动就存在的。
classloader加载Class的顺序是先委托其parent来加载,直到所有的parent都不能加载才自己去加载。
Was的类加载顺序
jvm加载器
参照上一部分的jvm类加载顺序
WebSphere extension classloader
这个层的classloader主要完成WAS运行时所需要的类以及相关资源,比如JDBC,Resource Adapter,以及用户扩展WAS运行时库的目录,这一层的委托策略都是父亲优先(PARENT_FIRST)。
WebSphere lib/app classloader
这个层的classloader主要是为了兼容WAS Version 4的。它主要用来加载一些所有应用都共享的类,在Version 4以后,推荐用Shared libraries来放需要共享的类库。
WebSphere service classloader
这层的classloader主要是来加载整个运行上当前服务器上的应用程序所共享的的类库,你可以通过定义特定的Shared libraries以来使当前的服务器中的应用程序共享它,这一层的委托策略是父亲优先(PARENT_FIRST)。
Application classloader
这一层由两个classloader组成:
第一个是Application Module Class loader,主要负责加载应用程序单元。对于应用程序中的Web单元,我们还可以设定用一个Web Module Class loader去加载(这时它的父亲就是Application Module Class loader),它是WAS classloader中的最底层。
对于这两个classloader,可以采取的委托策略可以既是父亲优(PARENT_FIRST),也可以父亲最后(PARENT_LAST)。
们还可以指点是单个Application Module Class loader去加载所有的应用程序或者每个应用程序都有自己的Application Module Class loader,这是也为更好的提高classloader的隔离性(Isolation),其选项分别为Multiple与Single。
Was 加载实践
1 WAS classloader的最佳实践:
1) 不要把应用程序依赖的资源放在JVM的系统lib下让JVM的classloader去加载,原因是如果应用程序的委托策略设成PARENT_LAST,可能会造ClassNotFoundException。
2) 不要修改ws.ext.dirs这个系统属性以此来增加WebSphere Extensions Classloader的加载能力,原因是被扩展的目录可能跟当前已经目录中有冲突,会导致一此不可预期的问题。
3) 如开启了动态重加载,这种情况下应用如果有对本地类库的依赖关系,最好使用WebSphere "server" Class loader来加载,这样服务器的整个生命周期这些库都能被应用程序可见,即使应用程序被重新加载。
2 实际WAS classloader的相关问题的分析与相应解决方案
如果在启动程序时出现如下异常:
· ClassCastException
· ClassNotFoundException
· NoClassDefFoundException
· UnsatisfiedLinkError
主要原因是未正确配置负责装入应用程序各单元的类装入器,可以查看一下当前应用程序的类加载结构。一般,我们可以从SystemOut.log这个log文件中找出当前的类加载路径设置,其中包括要加载的库以及还有WAS的扩展目录等。我们还可以利用WAS提供的Class Loader Viewer来更直接的看当前应用程序的类加载情况,方法如下:
单击Troubleshooting->Class Loader Viewer,进去后可以看到当前服务器上所有的应用程序,然后选取你关注的,然后会列出这个应用的所有组成单元,点击出现异常的那个单元,就会出现这个单元的classloader结构图,依次可以看到从顶到底的classloader结构图,并可以看到所有可以被加载的类或者类库。这样,可以分析当前出现的异常是不是因为不在这个单元的可加载视图里面,或者是不是因为跟别的当前能被加载的类有冲突。图2是一个查看实际应用程序的例子。
http://tech.sina.com.cn/s/2009-09-02/00351051784.shtml
记录一个关于tomcat下类加载的文章