zoukankan      html  css  js  c++  java
  • atitit。解决 No suitable Log constructor。。NoClassDefFoundError: org/apache/log4j/Category 找不到类的

    atitit解决 No suitable Log constructor。。NoClassDefFoundError: org/apache/log4j/Category 找不到类的 

    1. 深的层次原因::ClassLoader问题 1

    2. 排除流程 2

    3. 解决之道:: 2

    4. parent-first代理机制还是child-first代理机制 2

    4.1. Thread Context ClassLoader的出现 2

    5. 参考 3

    现象:

     org.apache.commons.logging.LogConfigurationException: No suitable Log constructor 

    Caused by: java.lang.NoClassDefFoundError: org/apache/log4j/Category

     

     

    1. 深的层次原因::ClassLoader问题

    ClassLoader问题可以分成三类:

    1.    抛出NoClassDefFoundError,即某个Logger相关的类对child ClassLoader来说是可见的,但是对parent ClassLoader来说则不可见。

    2.    非兼容性赋值,即两类虽然相同或存在父子关系,但是由于ClassLoader不一样而导致不可以相互赋值。

    在Java中,处于安全的考虑,从1.2开始引入代理机制,即在ClassLoader每次加载一个类时,首先去查找(代理给)parent ClassLoader是否存在该类的定义,如果有,则使用parent ClassLoader加载;否则,使用当前ClassLoader本身去加载该类。这样做可以阻止一些不安全的代码覆盖JDK内部的类,从而实现一些非法操作。Java文档中对该特性的描述如下:

    因而parent ClassLoader优先是Java中的默认原则。然而在Web Application中却建议使用child ClassLoader优先的机制,从而保证Web Application可以覆盖一些common的配置和JAR包,如Servlet的文档中对Web Application ClassLoader的描述如下:

     作者:: 老哇的爪子 Attilax 艾龙,  EMAIL:1466519819@qq.com

    转载请注明来源: http://blog.csdn.net/attilax

    2. 排除流程

    怀疑是jdklib哈面儿有class 优先加载..在查询自定义的种类的时候儿.走新不上兰..

     org.apache.commons.logging.LogConfigurationException ,点击查询,真的是jdk8中的..在找个log4j当然走心不死兰...

     

    3. 解决之道::

    不个comm.loigjdk删除.叫哪使用web appa的库... (推荐)

    要不走不个log4j类库copoy 到个jdk lib哈面儿,叫哪能行上..

    4. parent-first代理机制还是child-first代理机制

    因而parent ClassLoader优先是Java中的默认原则。然而在Web Application中却建议使用child ClassLoader优先的机制,从而保证Web Application可以覆盖一些common的配置和JAR包,如Servlet的文档中对Web Application ClassLoader的描述如下:

    其实以上这些不管是parent-first代理机制还是child-first代理机制都不是问题,问题出在由于Commons Logging应用太广泛了,导致很多Web服务器在实现时也使用了该包,然而又想保证不同Web Application中的日志配置不相互干扰,这样问题就来

    4.1. Thread Context ClassLoader的出现

    是为了解决一个框架在被Parent ClassLoader加载,然而它想加载Child ClassLoader中的类的需求,因而很多框架代码内部会使用Thread Context ClassLoader。比如在LogFactoryImpl的实现中就有很关于使用Thread Context ClassLoader的例子。Thread Context ClassLoader是需要手动设置的,不然默认为Parent Thread中的Thread Context ClassLoader。但是在实际过程中,Thread Context ClassLoader总是不会被正确的设置,比如以下代码注释掉的语句。

    默认情形哈::因为在没有正确的设置Thread Context ClassLoader时,当前的Thread Context ClassLoader是System ClassLoader。log4j对System ClassLoader是不可见的,而且LogFactory是System ClassLoader加载的,因而LogFactory根本找不到log4j包,从而导致即使在LoggerPrinterWithJCL中的日志打印语句还是使用了JDK Logging。而ParentFirstTestJCL0中使用JDK Logging则比较容易理解了。

    ,然而后来又出现了ClassNotFoundException(Category是Logger父类,要初始化Logger首先需要初始化其父类Catetory)是因为LogFactory这个实例是由System ClassLoader加载的,在Java中,在一个类要加载其他类时,使用加载该类的ClassLoader去加载要加载的类。所以在LogFactory实例去加载log4j中的Logger类时,使用的System ClassLoader,log4j包对System ClassLoader是不可见的,因而出现了ClassNotFoundException

    5. 参考

     

    org.apache.commons.logging.LogConfigurationException  No suitable Log constructorNoClassDefFoundError  org apache log4j Categor - 晚安,假行僧! 博客频道 - CSDN.NET.htm

    Commons Logging存在的ClassLoader问题详解 上善若水 - BlogJava.htm

  • 相关阅读:
    iOS新建项目基础设置
    Burp安装及配置(修改参数测试)
    打开他人代码,如何运行起来
    四、python用户交互程序
    三、python_字符编码与二进制
    二、python_变量要求
    一、python_(入门)
    linux 常用命令之一
    Atcoder Regular Contest 093 C
    「HNOI2016」序列
  • 原文地址:https://www.cnblogs.com/attilax/p/5963749.html
Copyright © 2011-2022 走看看