http://seanhe.iteye.com/blog/841723

由于平时项目中用到的还是JBoss 4.2.x所以我这里的分析时针对这个版本的,不一定适用其他JBoss版本。
下面言归正传。
JBoss为了实现类的共享引入了class loader repository的概念,并且设计了org.jboss.mx.loading.UnifiedClassLoader3 (UCL)来完成sharing classes的主要功能。
UCL和UnifiedLoaderRepository3 一对多的关系,默认情况下一个jboss实例中只有一个UnifiedLoaderRepository3实例,这个UnifiedLoaderRepository实例会和所有的UCL关联。
NoAnnotationClassLoader是UCL的父classloader用来加载$JBOSS_HOME/lib下的jar,system class loader是NoAnnotationClassLoader的父classloader。
这几个对象的关系请见下图

从上图可以看出默认情况下所有的UCL共享一个Repository,通过Repository可以实现class的共享。 UnifiedLoaderRepository3实例中维护着两个容器,一个是class cache:这个容器很明显缓存了一些class,这样可以提高loadClass方法的执行效率;另一个是packagesMap:这个map维护的是 类的包名和UCL的mapping关系。具体UCL按什么逻辑load class的请看下面的活动图:

UnifiedClassLoader3的继承结构如下图所示,UnifiedClassLoader3的父类RepositoryClassLoader重写了URLClassLoader的loadClass方法,实现了上图的逻辑

下面请看一下相关代码:
RepositoryClassLoader.java

Java代码  
  1. public Class loadClass(String name, boolean resolve)
  2. throws ClassNotFoundException
  3. {
  4. boolean trace = log.isTraceEnabled();
  5. if (trace)
  6. log.trace("loadClass " + this + " name=" + name+", loadClassDepth="+loadClassDepth);
  7. Class clazz = null;
  8. try
  9. {
  10. if (repository != null)
  11. {
  12. clazz = repository.getCachedClass(name);//先从cache中load class
  13. if (clazz != null)
  14. {
  15. if( log.isTraceEnabled() )
  16. {
  17. StringBuffer buffer = new StringBuffer("Loaded class from cache, ");
  18. ClassToStringAction.toString(clazz, buffer);
  19. log.trace(buffer.toString());
  20. }
  21. return clazz;
  22. }
  23. }
  24. //loadClassImpl中会调用的LoadMgr3的一些方法实现上面流程图的逻辑,具体的代码实现比较冗长,这里就不贴出来了
  25. clazz = loadClassImpl(name, resolve, Integer.MAX_VALUE);
  26. return clazz;
  27. }
  28. finally
  29. {
  30. if (trace)
  31. {
  32. if (clazz != null)
  33. log.trace("loadClass " + this + " name=" + name + " class=" + clazz + " cl=" + clazz.getClassLoader());
  34. else
  35. log.trace("loadClass " + this + " name=" + name + " not found");
  36. }
  37. }
  38. }

有几点结论可以加深一些印象:

  1. JBoss做为Application Server可以部署ear包也可以war包。但是jboss在默认情况下处理ear和war是两种class load机制。
  2. 当部署ear时,JBOSS默认使用我前面提到的class load机制。一个ear包里的所有的jar由一个UCL统一加载和管理
  3. 需要注意的是ear里的war的部署有点特别。它只是将自身添加到ucl的classpath域中,而war下的WEB-INF/lib/*.jar,则是由WebAppClassloader来加载

由于jboss对所有UCL的共享机制就会导致出现一些class的版本冲突问题,一些应用加载不到自己的应用需要的class。对于这个问题JBOSS提供了一些解决措施:http://community.jboss.org/wiki/ClassLoadingConfiguration。后面我会再整理一下此前我遇到过的一个class冲突的case和解决办法。

Tomcat6/7 class loader机制
Tomcat class loader层次结构

Tomcat的class load机制较Jboss来说要简单
当web应用需要load class时先调用WebAppClassloader的loadClass方法,loadClass内部逻辑如下:

  1. 调用findLoadedClass(String)检查此class是否已经加载,如果以加载则直接返回,如果没有则继续做下一步。
  2. 调用system class loader的loadClass的方法,这样可以加载到JDK核心的类,如果没有找到符合的类则继续做下一步。
  3. 如果WebAppClassloader的delegate属性是true或者正在处理的class在过滤列表里,会先从父class loader中加载类。如果没有则继续做下一步。一般这一步不会执行。
  4. WebAppClassloader在自己的类库(WEB-INF/classes和WEB-INF/lib)中查找class。如果没有则继续做下一步。
  5. 如果前面第3步已经跳过这一步会继续执行。如果前面第3步已经执行过,这一步就不会再执行。这一步的执行逻辑同第3步。

具体的代码可以看WebAppClassloader.loadClass(..)

参考文档:
http://community.jboss.org/wiki/JBossClassLoadingUseCases
http://community.jboss.org/wiki/ClassLoadingConfiguration
http://community.jboss.org/wiki/EnableClassloaderLogging
http://agapple.iteye.com/blog/791940

http://www.iteye.com/topic/826661

转载于:https://www.cnblogs.com/lingxue3769/archive/2012/03/01/2375997.html

JBoss、Tomcat Classloader不完全分析相关推荐

  1. 这篇文章绝对让你深刻理解java类的加载以及ClassLoader源码分析

    前言 package com.jvm.classloader;class Father2{public static String strFather="HelloJVM_Father&qu ...

  2. tomcat源码分析_CVE-2020-9484 tomcat session反序列化漏洞分析

    作者:N1gh5合天智汇 title: CVE-2020-9484 tomcat session反序列化漏洞分析 tags: CVE,Tomcat,反序列化 grammar_cjkRuby: true ...

  3. tomcat闪退原因分析

    tomcat闪退原因分析 tomcat闪退原因分析 第一种端口被占用 第二种jdk不匹配 第三种运行环境配置 分析tomcat环境变量配置 tomcat闪退总结 tomcat闪退原因分析 在学习jav ...

  4. 关于Jboss/Tomcat/Jetty的JNDI定义123

    貌似有段时间没来这里忽悠了,今天抽空接着忽悠下这三个服务器配置JNDI时的一些异同点并提点自己的建议. Jboss 4 Jboss中配置JNDI最常见的就是在配置数据源的时候,在server/defa ...

  5. 【Android 逆向】Dalvik 函数抽取加壳 ( 类加载流程分析 | ClassLoader#loadClass 函数分析 | BaseDexClassLoader#findClass 分析 )

    文章目录 一.ClassLoader.java#loadClass 类加载函数源码分析 二.BaseDexClassLoader.java#findClass 函数源码分析 一.ClassLoader ...

  6. Tomcat Filter 源码分析

    Filter 概述 Servlet API中提供了一个Filter接口,开发web应用时,如果编写的Java类实现了这个接口,则把这个java类称之为过滤器Filter. 通过Filter技术,开发人 ...

  7. Tomcat startup.bat 原理分析

    startup.bat 解析 验证CATALINA_HOME 环境变量是否设置,如果没有设置则通过CATALINA_HOME/bin目录下查找catalina.bat文件来确定CATALINA_HOM ...

  8. Jetty 与 Tomcat 比较,及性能分析

    主流java的web容器,主要是Tomcat, jboss, jetty, resin.由于以前我们主要用的是jboss4.0.5,但jbosse用的servlet容器是tomcat5.5,所以只进行 ...

  9. Tomcat内存溢出原因分析

    Tomcat内存溢出的原因  在生产环境中tomcat内存设置不好很容易出现内存溢出.造成内存溢出是不一样的,当然处理方式也不一样. 这里根据平时遇到的情况和相关资料进行一个总结.常见的一般会有下面三 ...

最新文章

  1. 经典笔试题: 二叉树中和为某一值的路径(路径总和)
  2. Android phone xp 华为3x,3000mAh大电池 华为荣耀3X续航能力实测
  3. python封装成exe后运行失败_Python的带pandas包的程序封装成exe 2018-01-11
  4. C语言高级编程:数组和指针作为函数形参
  5. java单链表 提供增删改查_java实现单链表增删改查的实例代码详解
  6. linux+右键快捷,LINUX 添加右键打开终端快捷方式
  7. 如何准确的判断一个数据的类型
  8. 接口(interface)有什么优点,为什么要用接口
  9. Django中Settings中Templates的路径设置
  10. 2020-12-04
  11. 微信清理僵尸粉系统源码
  12. mongodb 分片集群安装,以及环境准备
  13. c4d打开没反应_野分享:一大波C4D插件的测试以及分享
  14. 高斯过程回归(Gaussian Process Regression)
  15. 第三十一章 与昔一何殊勇怯(一之全)
  16. arduino步进电机程序库_Arduino步进电机控制示例
  17. 【2022省选模拟】星际航道——网格图最小生成树、LCT
  18. 数据结构与算法(Leetcode链表篇)
  19. lavavel 环境配置 summer版
  20. 智慧城市/园区三维GIS可视化平台

热门文章

  1. NHibernate中,查询SqlServer数据库多个实体对象
  2. java定义一个指针类型变量赋值吗,C++中指针的数据类型和运算相关知识小结
  3. Docker cgroups作用(十)
  4. linux进程--fork详解(二)
  5. python制作缩略图
  6. python怎么随机生成数据_Python-随机生成数据
  7. 鸿蒙2.0操作体验,鸿蒙2.0操作系统正式版-华为鸿蒙2.0操作系统正式版官方预约 v1.0.0-优盘手机站...
  8. 绘制简单的正太分布图
  9. 初学laravel migrate常见错误解决
  10. angular2 学习二 最简单的模板