解决tomcat下面部署多个项目log4j的日志输出会集中输出到一个项目中的问题
在一次项目上线后,发现了一个奇怪的问题,经过对源码的阅读调试终于解决,具体经过是这样的:
问题描述: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的日志输出会集中输出到一个项目中的问题的更多相关文章
- 使用log4j将日志输送到控制台、文件或数据库中
转: 使用log4j将日志输送到控制台.文件或数据库中 2018-09-07 00:45:08 keep@ 阅读数 2880更多 分类专栏: 其它 版权声明:本文为博主原创文章,遵循CC 4.0 ...
- 如何在Eclipse中彻底修改一个项目名称
在实际工作中,有时候为了赶时间,往往通过复制项目得到一个成型的框架.那么怎么才可以彻底修改项目名称呢? 1.web.xml 2.工作空间中找到当前项目下.project文件 3.工作空间中找到当前项目 ...
- 如何把VS2015中本地的一个项目建立远程的Git Repository
在项目开发中,我在本地自己电脑上用VS2015建立了一个项目,比如项目名字叫做Luke.Test 那么,接下来,我如何把这个项目签入到远程的Git Repository里去呢. 方法如下 先进入远程R ...
- 解决tomcat同时部署两个SpringBoot应用提示InstanceAlreadyExistsException
问题描述:Caused by: javax.management.InstanceAlreadyExistsException: com.alibaba.druid.pool:name=primary ...
- 解决tomcat同时部署两个SpringBoot应用报异常InstanceAlreadyExistsException
问题描述:Caused by: javax.management.InstanceAlreadyExistsException: com.alibaba.druid.pool:name=primary ...
- 关于Eclipse中复制粘贴一个项目后的操作
今天在做一个小Demo,内容和之前的项目有些类似就直接复制过来了,项目名修改了,web.xml的项目名也修改了,可是部署到Tomcat之后,以这个新项目名进行访问就会出现404的错误,只可以使用复制之 ...
- c# winform 在一个窗体中使用另一个窗体中TextBox控件的值——解决办法
[前提]一个winform应用程序项目中,窗体B,需要使用 窗体A 中一个TextBox控件的值,进行计算等操作. [解决方案] 1.在窗体A中定义:public static double a;// ...
- 如何在maven项目中引用领一个项目
1 有两个项目 maven01 和maven 02,想在maven 02中引用maven01的方法,该如何操作呢 maven01中Factory类中的方法 public class Factory ...
- IDEA中每次拷贝一个项目的时候必须标记一下配置文件resources,否则报错
随机推荐
- LintCode——Pour Water
Pour Water: We are given an elevation map, heights[i] representing the height of the terrain at that ...
- Laravel 5.6 视图用Blade语法传递变量和流程控制if 语句和循环语句
Laravel5.6 视图用Blade语法传递变量和流程控制if 语句和循环语句 Laravel 的 View 部分是内置了两套输出系统:直接输出和使用 Blade 引擎“编译”后输出,默认情况下它们 ...
- jmeter学习(1)基础支持+安装部署
1. Apache jmeter 是100%的java桌面应用程序 支持的协议有:WEB-HTTP/HTTPS , SOAP, FTP, JDBC, LDAP, MAIL, MongoDB ...
- PAT甲题题解-1101. Quick Sort (25)-大水题
快速排序有一个特点,就是在排序过程中,我们会从序列找一个pivot,它前面的都小于它,它后面的都大于它.题目给你n个数的序列,让你找出适合这个序列的pivot有多少个并且输出来. 大水题,正循环和倒着 ...
- Daily Scrum NO.1
工作概况 符美潇(PM): 今日工作 1.根据开发进程分配第一步开发工作,对相应的成员提出今日的开发要求:要求成员自己所负责的线程池,动态爬取,去重,文件分类等部分进行资料的相关了解. 2.Daily ...
- 20135234mqy-——信息安全系统设计基础第十二周学习总结
process environ.c environvar.c consumer.c 管道写端 producer.c 管道读端 testmf.c listargs.c pipedemo.c 管道 pip ...
- VMware 虚拟机CentOS 7 网路连接配置 无eth0简单解决办法
个人博客:http://www.cnblogs.com/miaojinmin799/ 在前面几步基本和网上linux配置差不多,最后一步要配置eth0时出现如图所示结果使用ifconfig -a命令 ...
- beta5
吴晓晖(组长) 过去两天完成了哪些任务 完善推荐算法 展示GitHub当日代码/文档签入记录 接下来的计划 推荐算法 还剩下哪些任务 组员:刘帅珍 过去两天完成了哪些任务: 修改原型,整理背景 明日计 ...
- Java Socket 多线程聊天室
本来这次作业我是想搞个图形界面的,然而现实情况是我把题意理解错了,于是乎失去了最初的兴致,还是把程序变成了功能正确但是“UI”不友好的console了,但是不管怎么样,前期的图形界面的开发还是很有收获 ...
- Visual studio 2013 安装的漫长过程
本周有一个任务是安装VS 2013版本,下载了安装包,七点多G,oh my god!!! 图上维持了两三个小时,可能我电脑台low了..... 因为是win7系统,需要进行重启电脑. 安装成功之后. ...