Tomcat 启动时类加载顺序

Keil C51开发必看:详解data/xdata/bdata内存分配陷阱与避坑指南 本文深入解析Keil C51开发中的data/xdata/bdata内存分配陷阱,提供针对51芯片的高效避坑指南。通过真实案例揭示Keil编译器的隐藏规则,分享内存优化策略和调试技巧,帮助开发者解决data溢出、xdata访问异常等典型问题,提升嵌入式开发效率。 阅读详情
  Tomcat的class加载的优先顺序一览  
  1.最先是$JAVA_HOME/jre/lib/ext/下的jar文件。  
  2.环境变量CLASSPATH中的jar和class文件。  
  3.$CATALINA_HOME/common/classes下的class文件。  
  4.$CATALINA_HOME/commons/endorsed下的jar文件。  
  5.$CATALINA_HOME/commons/i18n下的jar文件。  
  6.$CATALINA_HOME/common/lib   下的jar文件。  
  (JDBC驱动之类的jar文件可以放在这里,这样就可以避免在server.xml配置好数据源却出现找不到JDBC   Driver的情况。)  
  7.$CATALINA_HOME/server/classes下的class文件。  
  8.$CATALINA_HOME/server/lib/下的jar文件。  
  9.$CATALINA_BASE/shared/classes   下的class文件。  
  10.$CATALINA_BASE/shared/lib下的jar文件。  
  11.各自具体的webapp   /WEB-INF/classes下的class文件。  
  12.各自具体的webapp   /WEB-INF/lib下的jar文件。  
  class的搜寻顺序如下:  
  -------------  
  Bootstrap   classes   of   your   JVM    
  System   class   loader   classses   (described   above)    
  /WEB-INF/classes   of   your   web   application    
  /WEB-INF/lib/*.jar   of   your   web   application    
  $CATALINA_HOME/common/classes    
  $CATALINA_HOME/common/endorsed/*.jar    
  $CATALINA_HOME/common/i18n/*.jar    
  $CATALINA_HOME/common/lib/*.jar    
  $CATALINA_BASE/shared/classes    
  $CATALINA_BASE/shared/lib/*.jar    
  --------------  
  因此放在不同webapp里的class文件,会被classloader加载成不同的实例。  
  例如假设下面两个不同内容的class。分别放在不同的webapp的class目录下。  
  package   com.lizongbo;  
  public   class   TestClass   {  
      private   String   NAME="lizongbo";  
  }  
  package   com.lizongbo;  
  public   class   TestClass   {  
      private   String   NAME="li_zongbo";  
  }  
  在不同的webapp得到的com.lizongbo.NAME结果是不同的,且互不影响。  
  但是注意,以下包名开头的class例外:  
  javax.*    
  org.xml.sax.*    
  org.w3c.dom.*    
  org.apache.xerces.*    
  org.apache.xalan.*    
  ps,注意.在各个jar中的/META-INF/MAINFEST.MF文件里Class-Path键值对,也会提供jar的加载优先顺序。  
  例如某jar的MAINFEST.MF内容如下:  
  Manifest-Version:   1.0  
  Created-By:   lizongbo  
  Class-Path:   commons-beanutils.jar  
  Class-Path:   commons-collections.jar  
  Class-Path:   commons-dbcp.jar  
  Class-Path:   commons-digester.jar  
  Class-Path:   commons-logging.jar  
  Class-Path:   commons-pool.jar  
  Class-Path:   commons-services.jar  
  Class-Path:   commons-validator.jar  
  Class-Path:   jakarta-oro.jar  
  Main-Class:   com.lizongbo.MyTestClass  
  那么在加载这个jar的时候,会先在此jar所在目录下依次先加载commons-beanutils.jar,commons-collections.jar。。。等jar文件。  
  在不同的地方放置jar和class可能会产生意想不到的后果,,尤其是不同版本的jar文件,因此在实际应用部署web应用时候要特别留心.  
  例如   使用javamail常见的一个出错信息:  
  javax.mail.NoSuchProviderException:   No   provider   for   smtp  
  其真实原因就很可能如下:  
  在不同的加载jar的目录下放置了不同版本的mail.jar,比如一个是javamail1.3.1的mail.jar  
  在D:/jakarta-tomcat-5.5.8/common/lib下,而另外一个是javamail1.3.2的mail.jar在  
  D:/jakarta-tomcat-5.5.8/webapps/lizongbo/WEB-INF/lib下,  
  那么lizongbo这个webapp中使用到javamail进行邮件发送的时候,便会出现No   provider   for   smtp的错误。  
*******************************************************************
ClassLoader in Tomcat
************************************
1 - Tomcat 的类载入器的结构


Tomcat Server 在启动的时候将构造一个ClassLoader树,以保证模块的类库是私有的
Tomcat Server的ClassLoader结构如下:


        +-----------------------------+ 

        |         Bootstrap           | 

        |             |               | 

        |          System             | 

        |             |               | 

        |          Common             | 

        |         /      /            | 

        |     Catalina  Shared        | 

        |               /    /        | 

         |          WebApp1  WebApp2   | 

        +-----------------------------+


其中:
- Bootstrap - 载入JVM自带的类和$JAVA_HOME/jre/lib/ext/*.jar
- System - 载入$CLASSPATH/*.class
- Common - 载入$CATALINA_HOME/common/...,它们对TOMCAT和所有的WEB APP都可见
- Catalina - 载入$CATALINA_HOME/server/...,它们仅对TOMCAT可见,对所有的WEB APP都不可见
- Shared - 载入$CATALINA_HOME/shared/...,它们仅对所有WEB APP可见,对TOMCAT不可见(也不必见)
- WebApp - 载入ContextBase?/WEB-INF/...,它们仅对该WEB APP可见



2 - ClassLoader 的工作原理


每个运行中的线程都有一个成员contextClassLoader,用来在运行时动态地载入其它类
系统默认的contextClassLoader是systemClassLoader,所以一般而言java程序在执行时可以使用JVM自带的类、$JAVA_HOME/jre/lib/ext/中的类和$CLASSPATH/中的类
可以使用 Thread.currentThread().setContextClassLoader(...); 更改当前线程的contextClassLoader,来改变其载入类的行为


ClassLoader 被组织成树形,一般的工作原理是:
1) 线程需要用到某个类,于是contextClassLoader被请求来载入该类
2) contextClassLoader请求它的父ClassLoader来完成该载入请求
3) 如果父ClassLoader无法载入类,则contextClassLoader试图自己来载入


注意 :WebApp?ClassLoader的工作原理和上述有少许不同:
它先试图自己载入类(在ContextBase?/WEB-INF/...中载入类),如果无法载入,再请求父ClassLoader完成


由此可得:
- 对于WEB APP线程,它的contextClassLoader是WebApp?ClassLoader
- 对于Tomcat Server线程,它的contextClassLoader是CatalinaClassLoader



3 类的查找

ClassLoader类中loadClass方法为缺省实现,用下面的顺序查找类:

1、调用findLoadedClass方法来检查是否已经被加载。如果没有则继续下面的步骤。

2、如果当前类装载器有一个指定的委托父装载器,则用委托父装载器的loadClass方法加载类,也就是委托给父装载器加载相应的类。

3、如果这个类装载器的委托层级体系没有一个类装载器加载该类,则使用类装载器定位类的特定实现机制,调用findClass方法来查找类。



4 - 部分原代码分析


4.1 - org/apache/catalina/startup/Bootstrap.java

Bootstrap中定义了三个classloader:commonLoader,catalinaLoader,sharedLoader.三者关系如下:


// 注意三个自己定置的ClassLoader的层次关系: 

            // systemClassLoader (root) 

              //   +--- commonLoader 

            //          +--- catalinaLoader 

            //          +--- sharedLoader


Tomcat Server 线程的起点
构造ClassLoader树,通过Thread.currentThread().setContextClassLoader(catalinaLoader)设置当前的classloader为catalinaLoader。
载入若干类,然后转入org.apache.catalina.startup.Catalina类中



4.2 org.apache.catalina.loader.StandardClassLoader.java

通过看loadClass这个方法来看tomcat是如何加载类的,顺序如下:

(0) Check our previously loaded class cache查找已经装载的class
        clazz = findLoadedClass(name);

(1) If a system class, use system class loader通过系统classloader来装载class

        ClassLoader loader = system;
            clazz = loader.loadClass(name);

(2) Delegate to our parent if requested如果有代理则使用父类classloader

            ClassLoader loader = parent;
            if (loader == null)
                loader = system;
            clazz = loader.loadClass(name);

(3) Search local repositories 查找本地类池,比如$CATALINA_HOME/server

           clazz = findClass(name);

(4) Delegate to parent unconditionally 默认使用代理装载器



[ 查看代码]


4.3 - org/apache/catalina/startup/ClassLoaderFactory.java


根据设置创建并返回StandardClassLoader的实例


[ 查看代码]


4.4 - org/apache/catalina/loader/StandardClassLoader.java


类载入器


4.5 - org/apache/catalina/startup/SecurityClassLoad.java


该类仅包含一个静态方法,用来为catalinaLoader载入一些类


[ 查看代码]


Appendix - 参考


[1] http://jakarta.apache.org/tomcat/ 中的Tomcat 4.1.x文档Class Loader HOW-TO


在一个 JVM 中可能存在多个 ClassLoader ,每个 ClassLoader 拥有自己的 NameSpace 。一个 ClassLoader 只能拥有一个 class 对象类型的实例,但是不同的 ClassLoader 可能拥有相同的 class 对象实例,这时可能产生致命的问题。如 ClassLoaderA ,装载了类 A 的类型实例 A1 ,而 ClassLoaderB ,也装载了类 A 的对象实例 A2 。逻辑上讲 A1=A2 ,但是由于 A1 和 A2 来自于不同的 ClassLoader ,它们实际上是完全不同的,如果 A 中定义了一个静态变量 c ,则 c 在不同的 ClassLoader 中的值是不同的。

 

【VibeCoding系列】小白入门指南:模型选择、编辑器选择、项目预定全分析 开箱即用:下载安装就能用,不用配 API Key(也可以自己配)Cmd+K 快速修改:选中代码,按 Cmd+K,直接让 AI 修改Cmd+L 对话:侧边栏聊天,支持引用文件和代码@文件引用:输入 @ 就能引用项目中的文件,AI 自动读取上下文Agent 模式:告诉 AI 一个需求,它自动跨文件修改下载地址cursor.com(免费版有额度限制,足够入门)✅下载 Cursorcursor.com),安装打开✅选一个小项目(个人名片页 or Todo List)✅按照七步工作流开干。 阅读详情

相关推荐

CIC-IDS-2018数据集高效预处理实战:从数据清洗到特征整合

本文详细介绍了CIC-IDS-2018数据集的高效预处理方法,从数据清洗到特征整合的全流程实战。通过内存优化、异常值处理和特征工程等技巧,帮助网络安全研究人员快速处理大规模网络流量数据,提升机器学习模型的训练效率和准确率。特别针对特征数据的预处理提供了实用代码示例和优化建议。

weixin_29274969的博客 502

tomcat加载顺序

以 filter 为例,web.xml 中当然可以定义多个 filter,与 filter 相关的一个配置节是 filter-mapping,这里一定要注意,对于拥有相同 filter-name 的 filter 和 filter-mapping 配置节而言,filter-mapping 必须出现在 filter 之后,否则当解析到 filter-mapping 时,它所对应的 filter-name 还未定义。最终得出的结论是:listener -> filter -> servlet。

1786

神联动:LSTM+卡尔曼滤波!一区大门轻松开!

近来热度飙升,成为时间序列预测和状态估计等领域的香饽饽,非常好发高区!主要在于:这两者结合,不仅能提高模型预测准确性;还能拓展应用场景,为我们的论文创新提供发挥空间,且当下还在蓝海阶段,还不算卷。具体点说:卡尔曼滤波擅长处理线性状态估计和噪声,能使LSTM更好地适应动态环境的变化,减少噪声干扰,降低预测误差。而LSTM通过捕捉长期依赖关系,擅长处理非线性时间序列,能够弥补卡尔曼滤波在这方面的不足,从而把应用场景从传统的状态估计,延伸到金融预测、工业检测、自动驾驶等任务。

2401_82426425的博客 2209

Tomcat 多应用启动,应用启动顺序设置

Tomcat 配置

weixin_46883180的博客 2154

AUTOSAR—TM模块介绍及使用概要

根据所要测量的场景不同,有1us16bit、1us24bit、1us32bit、100us32bit四种类型可选;TM模块在服务层,提供一些基于时间的服务功能,如测量CPU和任务的负载,周期执行一些回调函数。2、对于需要在不同时间执行不同逻辑的周期任务中,可以搭建时间状态机:参考Tm用户手册;定时器复位、获取时间宽度、定时器转换、定时器同步、繁忙等待。偏移定时器实例的参考时间,直接将定时器数值进行偏移;以1us16bit定时器类型为例,讲几个常用函数。同步两个定时器,把源定时器时间值给到目的定时器。

qq_42479987的博客 605

Java utgard连接OPC问题记录

怎么开启是个问题, 是在引入openscada的jar包里的Sever类中修改,这就犯难了, 其实没必要, 只要在自己项目下创建与openscada中Server类相同的路径,并复制Server过去改就行了, 项目会优先使用本地类,像下面这样。奇迹发生了,0x00000005解决. 注: 我的安全补丁编码跟网上查到的并不一样, 所以最初没有删,后来全都删了就好了,这个编码规则咱也不知道.安全日志中记录用户登录行为, OPC通信需要使用Windows系统用户进行登录, 如果用户名密码错误这里会有相关记录.

wangxin1949的博客 2840

jar冲突问题与Tomcat 加载jar的顺序

前言 笔者在解决业务问题的时候,很多业务提出了为啥我的服务在测试环境啥问题都没有,发布生产就出问题了,第一反应是配置不一样?????实际上部分原因可能还与发布的容器有关,比如Tomcat8,比如jar冲突。刚好解决了jar冲突的事情,总结分析原因。 1. tomcat源码下载 Tomcat的新版本是可以直接下载源码的,但是Tomcat7就只能 Index of /dist/tomcat (apache.org) 记得下载src 2. tomcat 7与tomcat 8的区别 以非嵌

fenglllle的博客 3437

从零到一:使用阿里云百炼搭建企业级 AI Agent 完全实战手册(2026超详细版)

本文是一份企业级AI Agent构建手册,主要面向企业技术负责人、AI产品经理和后端开发工程师。手册详细介绍了如何在阿里云百炼平台上搭建企业智能体应用的全流程,包括环境准备、知识库构建、智能体创建、工具集成、工作流编排等核心环节。重点内容包括: 准备工作:阿里云账号注册、百炼服务开通、免费额度领取、API Key管理 知识库构建:文档格式要求、内容优化原则、RAG系统搭建 智能体开发:Agent创建、工具集成、复杂业务工作流设计 生产部署:多渠道接入、监控运维、安全治理 成本控制:Token预算管理、选型决

u010323587的专栏 1091

tomcat按顺序启动应用

前提,必须保留tomcat自带的管理应用manager。

u012851114的博客 813

2023年LitCTF web组wp

1、导弹迷踪2、1zjs3、php是世界上最好的语言!!4、Ping5、我Flag呢?7、作业管理系统8、Vim yyds10、这是什么?SQL!注一下!11、Flag点击就送!12、就当无事发生13、彩蛋。

m0_74160536的博客 1591

CoppeliaSim和Python进行无人机联合仿真

CopeeliaSim和Python进行无人机轨迹跟踪联合仿真。首先建立起CoppeliaSim和Python的连接,其次在Python中生成轨迹,CoppeliaSim仿真环境中的无人机进行跟踪,并绘制出轨迹曲线,有每一步详细的教学。

加斯顿工程师的博客 987

Tomcat启动时类加载顺序及运行时类载入顺序

Tomcat启动时类加载顺序 第一阶段: JVM启动相关 1.$JAVA_HOME/jre/lib/ext/*.jar 2.环境变量CLASSPATH中的*.jar和*.class 第二阶段: TOMCAT启动相关 1.$CATALINA_HOME/common/classes/*.class 2.$CATALINA_HOME/commons/endorsed/*.jar...

syq8023的博客 2462

[Godot][入门] 安装与版本选择:3.x 还是 4.x?(按项目类型一键决策)

摘要: Godot引擎版本选择需根据项目需求权衡3.x与4.x。Godot4.x(如4.2)适合3D开发和新项目,支持Vulkan和GDScript2.0,但生态尚不成熟;Godot3.x(如3.5.3)则更适合稳定2D开发、Web导出及依赖现有插件/教程的场景。安装方式极简,官网下载解压即可运行。新手建议:短期高效选3.x,长期探索选4.x,旧项目勿盲目迁移。附版本对比表及决策树,助开发者快速匹配需求。

技术小甜甜:传播可落地技术,帮助个人和企业降低解决真实场景问题的成本 910

Tomcat启动时类加载顺序

Tomcat启动时类加载顺序  第一阶段:  JVM启动相关  1.$JAVA_HOME/jre/lib/ext/*.jar   2.环境变量CLASSPATH中的*.jar和*.class  第二阶段:  TOMCAT启动相关  1.$CATALINA_HOME/common/classes/*.class   2.$CATALINA_HOME/commons/endorse

Free Lander 3358

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

Tomcat启动时classloader加载顺序

<br />Tomcat启动时classloader加载顺序 <br />Tomcat的class加载的优先顺序一览   <br />1.最先是$JAVA_HOME/jre/lib/ext/下的jar文件。   <br />2.环境变量CLASSPATH中的jar和class文件。   <br />3.$CATALINA_HOME/common/classes下的class文件。   <br />4.$CATALINA_HOME/commons/endorsed下的jar文件。   <br />5.$CAT

天乙贵人 4795

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

Tomcat类加载机制和JAVA类加载机制的比较

图解Tomcat类加载机制   说到本篇的tomcat类加载机制,不得不说翻译学习tomcat的初衷。   之前实习的时候学习javaMelody的源码,但是它是一个Maven的项目,与我们自己的web项目整合后无法直接断点调试。后来同事指导,说是直接把java类复制到src下就可以了。很纳闷....为什么会优先加载src下的java文件(编译出的class),而不是jar包...

weixin_30830327的博客 133

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

tomcat中class和jar的加载顺序

当我们启动一个tomcat的服务的时候,jar包和claess文件是是以怎么样的顺序被加载进来的?   加载顺序: 1. $java_home/lib 目录下的java核心api  2. $java_home/lib/ext 目录下的java扩展jar包 3. java -classpath/-Djava.class.path所指的目录下的类与jar包 4. $

dns007 6230

class没有发布到tomcat_面试官:Java 类在 Tomcat 中是如何加载的?

说到本篇的Tomcat类加载机制,不得不说翻译学习Tomcat的初衷。之前实习的时候学习JavaMelody的源码,但是它是一个Maven的项目,与我们自己的Web项目整合后无法直接断点调试。后来同事指导,说是直接把Java类复制到src下就可以了。很纳闷....为什么会优先加载src下的Java文件(编译出的class),而不是jar包中的class呢?现在了解Tomcat的类加载机制...

weixin_39794385的博客 125

Tomcat ClassLoader

总结 WebApp?ClassLoader的工作原理和上述有少许不同: 它先试图自己载入类(在ContextBase?/WEB-INF/...中载入类),如果无法载入,再请求父ClassLoader完成 由此可得: - 对于WEB APP线程,它的contextClassLoader是WebApp?ClassLoader - 对于Tomcat Server线程,它的co

For that dream 1444

关于Tomcat首页配置,类加载顺序以及优先级

啦啦啦

HQqHQhqqhq的博客 2474
上一篇: 设置weblogic的jvm大小三个方法
下一篇: struts2重启tomcat后的错误的排除过程
Ice008
博客等级 码龄19年 34粉丝 36原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值