在一次项目上线后,发现了一个奇怪的问题,经过对源码的阅读调试终于解决,具体经过是这样的:

问题描述:tomcat7下面部署多个项目,log4j的日志输出会集中输出到一个项目中,就算配置了日志文件的绝对路径也是一样的。

解决方法:log4j.jar在每个项目中单独加到lib下

解决过程:先从log4j入手分析,在项目启动时调试org.apache.log4j.FileAppender,输出获取文件路径是绝对路径,应该是没有问题的,其实在正常的启动下也会输出该日志
信息: Set web app root system property: 'RootPath' = [H:\Project\.metadata\.plugins\org.eclipse.wst.server.core\tmp1\wtpwebapps\cpa-1.0\]
信息: Set web app root system property: 'CpaRootPath' = [H:\Project\.metadata\.plugins\org.eclipse.wst.server.core\tmp1\wtpwebapps\cpa\]
log4j是基于spring进行初始化的,到这里怀疑是spring容器实例化作用域是否有问题,但是本地调试又正常的,发布到tomcat才有问题,好奇看了一下之前的部署的项目,发现日志是没有影响的;

  调试log4j的初始化源码,使用PropertyConfigurator.configure(configFilename)进行初始化测试,日志的输出路径配置会被addAppender到LogManager.getLoggerRepository()实例的repositorySelector变量中,而LogManager中的repositorySelector是静态初始化的;当然到目前为止仍然不会有问题,关键是tomcat的jar共享,放在shared/lib下面的共享包会被URLClassLoader加载,单独放到项目lib下面的jar包会被WebAppClassLoader加载,区别就在这里,关于URLClassLoader和WebAppClassLoader加载为什么会引起这种问题还要继续深入分析tomcat启动加载。

  了解Java和JVM的一定知道,JVM中通常有三层默认的类加载器,分别是启动(Bootstrap)类加载器、标准扩展(Extension)类加载器和系统(System)类加载器。这三者每两者间都是父子关系,即前者是后者的父亲或者双亲类加载器,并由此构建了一个“双亲委派关系”,或叫“代理”关系。当Java虚拟机要加载一个类时,到底派出哪个类加载器去加载呢?

  • 首先当前线程的类加载器去加载线程中的第一个类(假设为类A)。

    注:当前线程的类加载器可以通过Thread类的getContextClassLoader()获得,也可以通过setContextClassLoader()自己设置类加载器。

  • 如果类A中引用了类B,Java虚拟机将使用加载类A的类加载器去加载类B。
  • 还可以直接调用ClassLoader.loadClass()方法来指定某个类加载器去加载某个类。

  上面是jvm加载class的加载器,当tomcat启动时会为每个app分配了一个WebappClassLoader ,这样来避免多个app会加载相同jar包的问题,WebappLoader的parent是org.apache.catalina.loader.WebappClassLoaderBase,细看源码WebappClassLoaderBase直接继承于java.net.URLClassLoader类,最终继承于java.lang.ClassLoader类这样多个app就能共享tomcat的类库;WebappClassLoader的源码中发现,在进行findClass时会先试图自己加载类,找不到则请求parent来加载,这里和java的双亲委托模式是不同的,所以如果log4j放到项目lib下面会被当前项目的WebAppClassLoader加载并初始化静态实例,因为每个项目都被单独分配了WebAppClassLoader,这样jvm就能区分来自不同项目的各个类(热部署使用的就是该技术)。

总结:如果不深入的了解jvm和tomcat类加载器是很理解该问题是如何解决的,经过分析源码,并写了demo进行测试才实践出上述结论,实践出真理!

解决tomcat下面部署多个项目log4j的日志输出会集中输出到一个项目中的问题的更多相关文章

  1. 使用log4j将日志输送到控制台、文件或数据库中

    转: 使用log4j将日志输送到控制台.文件或数据库中 2018-09-07 00:45:08 keep@ 阅读数 2880更多 分类专栏: 其它   版权声明:本文为博主原创文章,遵循CC 4.0 ...

  2. 如何在Eclipse中彻底修改一个项目名称

    在实际工作中,有时候为了赶时间,往往通过复制项目得到一个成型的框架.那么怎么才可以彻底修改项目名称呢? 1.web.xml 2.工作空间中找到当前项目下.project文件 3.工作空间中找到当前项目 ...

  3. 如何把VS2015中本地的一个项目建立远程的Git Repository

    在项目开发中,我在本地自己电脑上用VS2015建立了一个项目,比如项目名字叫做Luke.Test 那么,接下来,我如何把这个项目签入到远程的Git Repository里去呢. 方法如下 先进入远程R ...

  4. 解决tomcat同时部署两个SpringBoot应用提示InstanceAlreadyExistsException

    问题描述:Caused by: javax.management.InstanceAlreadyExistsException: com.alibaba.druid.pool:name=primary ...

  5. 解决tomcat同时部署两个SpringBoot应用报异常InstanceAlreadyExistsException

    问题描述:Caused by: javax.management.InstanceAlreadyExistsException: com.alibaba.druid.pool:name=primary ...

  6. 关于Eclipse中复制粘贴一个项目后的操作

    今天在做一个小Demo,内容和之前的项目有些类似就直接复制过来了,项目名修改了,web.xml的项目名也修改了,可是部署到Tomcat之后,以这个新项目名进行访问就会出现404的错误,只可以使用复制之 ...

  7. c# winform 在一个窗体中使用另一个窗体中TextBox控件的值——解决办法

    [前提]一个winform应用程序项目中,窗体B,需要使用 窗体A 中一个TextBox控件的值,进行计算等操作. [解决方案] 1.在窗体A中定义:public static double a;// ...

  8. 如何在maven项目中引用领一个项目

    1 有两个项目 maven01  和maven 02,想在maven 02中引用maven01的方法,该如何操作呢 maven01中Factory类中的方法 public class Factory ...

  9. IDEA中每次拷贝一个项目的时候必须标记一下配置文件resources,否则报错

随机推荐

  1. Bitcoin挖矿

    目录 为什么要挖矿? 比特币挖矿 为什么要挖矿? 增加恶意行为的成本 增加记账权力,获取相应的奖励 比特币挖矿 每开采210000个区块,挖矿奖励减半 2009年1月-2012年11月,奖励50BTC ...

  2. Appium+Python3+ Android入门

    前言: Appium 是一个自动化测试开源工具,支持 iOS 平台和 Android 平台上的原生应用,web 应用和混合应用. 一.环境配置 1.安装Node.js https://nodejs.o ...

  3. centos 升级python2.6 到python3.3(实测可行)

    http://blog.csdn.net/harith/article/details/17538233

  4. 20135202闫佳歆--week2 操作系统是如何工作的--学习笔记

    此为个人学习笔记存档 week 2 操作系统是怎么工作的 一.计算机是如何工作的?--三个法宝 (一)三个法宝 1.存储程序计算机 所有计算机的基础性的逻辑框架. 2.函数调用堆栈 在低级语言中并不很 ...

  5. BFS和DFS算法

    昨晚刚昨晚华为笔试题,用到了BFS和DFS,可惜自己学艺不精,忘记了实现原理,现在借用大佬写的内容给自己做个提高 转自:https://www.jianshu.com/p/70952b51f0c8 图 ...

  6. DeepID人脸识别算法之三代

    DeepID人脸识别算法之三代 转载请注明:http://blog.csdn.net/stdcoutzyx/article/details/42091205 DeepID,眼下最强人脸识别算法.已经三 ...

  7. NetFPGA Demo ——reference_nic_nf1_cml

    NetFPGA Demo --reference_nic_nf1_cml 实验平台 OS:deepin 15.4 开发板:NetFPGA_1G_CML 实验过程 从NetFPGA-1G-CML从零开始 ...

  8. week5-Link Layer

    Technology:Internets and Packets course Layer 1 : Link Introduction/The Link Layer moving from histo ...

  9. maven项目无法读取src/main/java目录下的配置文件解决方法

    我们在用Mybatis去操作底层数据库的时候,需要用到xml配置文件,一般我们是把配置文件和dao放置在同一层目录.但是在用idea操作maven项目的时候,我们可能会遇到无法读取到dao对应的map ...

  10. IOS中@property的属性weak、nonatomic、strong、readonly等介绍

    iOS开发中@property的属性weak nonatomic strong readonly等介绍 //property:属性://synthesize:综合; @property与@synthe ...