`

JBoss、Tomcat Classloader不完全分析

    博客分类:
  • java
阅读更多
由于平时项目中用到的还是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
public Class loadClass(String name, boolean resolve)
      throws ClassNotFoundException
   {
      boolean trace = log.isTraceEnabled();
      if (trace)
         log.trace("loadClass " + this + " name=" + name+", loadClassDepth="+loadClassDepth);
      Class clazz = null;
      try
      {
         if (repository != null)
         {
            clazz = repository.getCachedClass(name);//先从cache中load class
            if (clazz != null)
            {
               if( log.isTraceEnabled() )
               {
                  StringBuffer buffer = new StringBuffer("Loaded class from cache, ");
                  ClassToStringAction.toString(clazz, buffer);
                  log.trace(buffer.toString());
               }
               return clazz;
            }
         }
         //loadClassImpl中会调用的LoadMgr3的一些方法实现上面流程图的逻辑,具体的代码实现比较冗长,这里就不贴出来了
         clazz = loadClassImpl(name, resolve, Integer.MAX_VALUE);
         return clazz;
      }
      finally
      {
         if (trace)
         {
            if (clazz != null)
               log.trace("loadClass " + this + " name=" + name + " class=" + clazz + " cl=" + clazz.getClassLoader());
            else
               log.trace("loadClass " + this + " name=" + name + " not found");
         }
      }
   }

有几点结论可以加深一些印象:
  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
分享到:
评论

相关推荐

    apache-tomcat-6.0.20

    首先,Tomcat是Java EE(Enterprise Edition)的一部分,但仅实现了Servlet和JSP规范,因此它被归类为轻量级应用服务器,与全功能的应用服务器如JBoss或WebLogic相比,它的内存占用和系统资源需求更低,适合小型到...

    spring-boot-web-JBoss5

    这是不完整的。 忘记删除 spring-boot-starter-tomcat。 java.lang.UnsupportedClassVersionError: org/apache/catalina/authenticator/FormAuthenticator : Unsupported major.minor version 51.0 at java.lang...

    java class加密保护(完全免费) v2.1

    Tomcat、Jboss等Java application server修改启动脚本, 把执行java的命令行后面加上参数-agentlib:<动态链接库文件所在路径>\classloader 适应环境: 操作系统:所有操作系统,Windows系统、Linux/Unix,只是运行...

    应用服务架构及性能调优详解

    内容概要:该文档介绍了常见的三种Java应用服务器(JBoss, Tomcat, Jetty)的整体架构及其启动流程,并深入探讨了它们各自的特性与配置要点。此外,文中还详细阐述了应用服务器的关键组件如类加载器(ClassLoader)的...

    java class加密保护工具

    Tomcat、Jboss等Java application server修改启动脚本, 把执行java的命令行后面加上参数-agentlib:<动态链接库文件所在路径>\classloader 适应环境: 操作系统:所有操作系统,Windows系统、Linux/Unix,只是运行...

    Java类加密工具v2.2(免注册)

    Tomcat、Jboss等Java application server修改启动脚本, 把执行java的命令行后面加上参数-agentlib:<动态链接库文件所在路径>\classloader 适应环境: 操作系统:所有操作系统,Windows系统、Linux/Unix,只是...

    我心飞扬java类加密工具2.1(亲测可用)

    Tomcat、Jboss等Java application server修改启动脚本,把执行java的命令行后面加上参数-agentlib:<动态链接库文件所在路径>\classloader 适应环境: 操作系统:所有操作系统,Windows系统、Linux/Unix,只是运行...

    java类加密工具v2.1

    Tomcat、Jboss等Java application server修改启动脚本, 把执行java的命令行后面加上参数-agentlib:<动态链接库文件所在路径>\classloader 适应环境: 操作系统:所有操作系统,Windows系统、Linux/Unix,只是运行...

    Java类加密2.0版本,无限制

    JBOSS等JAVA Application Server(应用服务器),修改启动脚本,把执行java的命令行加上参数-agentlib:<所在路径>\lanswon 适用环境 操作系统:Windows 98/2000/XP 等Windows系统 JDK:1.5.0及以上版本

    Java类加密程序

    自定义main方法),运行java时,带上参数-agentlib:<所在路径>\hidea Tomcat等JAVA Web Server,修改启动脚本,把执行java的命令行加上参数-agentlib:<所在路径>\hidea JBOSS等JAVA Application Server...

    出现几率最高和覆盖范围最广的一套经典Java面试题.docx

    23. **开源项目**:例如,Apache Tomcat是流行的Servlet容器,Hibernate是ORM框架,Spring框架提供了全面的企业级应用解决方案,MySQL是开源数据库等。 24. **Java书籍**:经典的Java书籍包括《Effective Java》、...

    超级有影响力霸气的Java面试题大全文档

    但通常情况下,由于Java Bean是被容器所创建(如Tomcat)的,所以Java Bean应具有一个无参的构造器,另外,通常Java Bean还要实现Serializable接口用于实现Bean的持久性。Java Bean实际上相当于微软COM模型中的本地...

    阿里面试题目总结.pdf

    19. **应用服务器JVM调优**:在WebLogic、Tomcat、JBoss等应用服务器上进行JVM参数优化,提升系统性能。 20. **离职原因**:展示你的职业规划和对新工作的期待,体现你的成长性和适应性。 面试中,除了技术知识,...

    java面试题

    - **Tomcat**、**WebLogic**、**JBoss**、**WebSphere** 等是一些常用的Java应用服务器。 ### 17. 线程的状态 - Java线程有多种状态,包括新建(`NEW`)、就绪(`RUNNABLE`)、阻塞(`BLOCKED`)、等待(`WAITING`)、超时...

    java程序员的标准

    - **Class Loaders**:负责加载类到JVM中,包括Bootstrap ClassLoader、Extension ClassLoader和Application ClassLoader等。 - **Class Reflection**:支持运行时检查类的信息并进行动态调用。 - **Garbage ...

    Java学习的30个目标.txt

    - **类加载器**:了解类加载过程,掌握Bootstrap ClassLoader、Extension ClassLoader和App ClassLoader的工作机制。 - **类的反射**:进一步探索Java反射机制,学习如何通过反射动态地创建和操作对象。 - **垃圾...

    Java学习思路.pdf

    Java应用服务器是指支持Java应用运行的服务器软件,文档中提到了几种常见的Java应用服务器,包括Jboss、Websphere、Weblogic。这些应用服务器对于Java的Web应用开发和企业级应用部署至关重要。例如,Tomcat是一个...

    JAVA面试题从基础到高级篇.doc

    3. 应用服务器如Tomcat、WebLogic、Jboss,提供部署、管理应用服务,支持EJB等。 4. 连接池提高数据库访问效率,减少创建和销毁连接的开销。 5. web.xml是Web应用的部署描述符,配置Servlet、过滤器、监听器等。 四...

    Java进阶路线

    - **Nginx, Apache, Tomcat, JBoss, Jetty**:常用的Web服务器。 - **HTML/CSS/JS**:前端技术的基础。 - **JS框架**:React, Angular, Vue.js 等。 - **单点登录, Session同步, SpringSecurity**:安全相关的技术和...

Global site tag (gtag.js) - Google Analytics