java - Log4j 自定义 Appender 最初抛出 ClassNotFoundException?

标签 java log4j

我有以下 log4j.xml 文件,其中使用 Log4J 自定义 Appender

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
   <appender class="org.apache.log4j.RollingFileAppender" name="FILE">
      <param value="${logfile}" name="File" />
      <param value="10" name="MaxBackupIndex" />
      <param value="200MB" name="MaxFileSize" />
      <layout class="org.apache.log4j.PatternLayout">
         <param value="%d[%t] %-5p(%F:&lt;%M&gt;:%L)- %m%n" name="ConversionPattern" />
      </layout>
   </appender>

   <appender class="com.ubsc.at.properties.CustomAppender" name="CUSTAPPEN">
    <layout class="org.apache.log4j.PatternLayout">
         <param value="%m" name="ConversionPattern" />
      </layout>
      </appender>

   <appender class="org.apache.log4j.AsyncAppender" name="ASYNC">
     <param name="Blocking" value="false"/>
     <param name="BufferSize" value="1000"/>
      <appender-ref ref="CUSTAPPEN" />
   </appender>

   <root>
      <level value="${logLevel}" />
      <appender-ref ref="FILE" />
      <appender-ref ref="ASYNC" />
   </root>
</log4j:configuration>

当应用程序启动时,我在 jetty 控制台中收到以下异常

java.lang.ClassNotFoundException: com.ubsc.at.properties.CustomAppender
        at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:169)
        at org.apache.log4j.helpers.Loader.loadClass(Loader.java:198)
        at org.apache.log4j.xml.DOMConfigurator.parseAppender(DOMConfigurator.java:247)
        at org.apache.log4j.xml.DOMConfigurator.findAppenderByName(DOMConfigurator.java:176)
        at org.apache.log4j.xml.DOMConfigurator.findAppenderByReference(DOMConfigurator.java:191)
        at org.apache.log4j.xml.DOMConfigurator.parseAppender(DOMConfigurator.java:284)
        at org.apache.log4j.xml.DOMConfigurator.findAppenderByName(DOMConfigurator.java:176)
        at org.apache.log4j.xml.DOMConfigurator.findAppenderByReference(DOMConfigurator.java:191)
        at org.apache.log4j.xml.DOMConfigurator.parseChildrenOfLoggerElement(DOMConfigurator.java:523)
        at org.apache.log4j.xml.DOMConfigurator.parseRoot(DOMConfigurator.java:492)
        at org.apache.log4j.xml.DOMConfigurator.parse(DOMConfigurator.java:1001)
        at org.apache.log4j.xml.DOMConfigurator.doConfigure(DOMConfigurator.java:867)
        at org.apache.log4j.xml.DOMConfigurator.doConfigure(DOMConfigurator.java:773)
        at org.apache.log4j.helpers.OptionConverter.selectAndConfigure(OptionConverter.java:483)
        at org.apache.log4j.LogManager.<clinit>(LogManager.java:127)
        at org.slf4j.impl.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:73)
        at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:242)
        at org.eclipse.jetty.util.log.Slf4jLog.<init>(Slf4jLog.java:44)
        at org.eclipse.jetty.util.log.Slf4jLog.<init>(Slf4jLog.java:27)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
        at java.lang.Class.newInstance0(Class.java:355)

我发现问题是 log4j 在加载我的类之前初始化。

如何避免此错误?将类文件复制到现有的 log4j.jar 中并创建一个新的 jar?

请分享您的想法。有什么方法可以设置我的 CustomAppender 只为我的应用程序包加载它?

最佳答案

如上所述,您遇到了类加载器问题。

如果您是从父类加载器或从 web 应用 URLClassLoader 加载 slf4J+Log4J,很难从您的堆栈跟踪中猜测(需要更多)。

无论如何,如果 slf4J 和 log4j 安装在 jetty /lib 文件夹中(例如很可能由 jetty 父类加载器加载),则任何自定义附加程序都应该位于同一 /lib 文件夹中的 jar 中。

或者,您可以尝试以下方法(未经测试):

  1. 从“标准”log4j 配置文件开始(无自定义附加程序)
  2. 将自定义附加程序的类放入 web 应用的 WEB-INF/lib 文件夹中的 jar 中,或者直接在 WEB-INF/classes 中使用这些类
  3. 重写 servlet 的 ìnit 方法,以编程方式在 Log 4j 记录器上加载自定义附加程序。类似的东西

    Logger.getLogger( "my.package").addAppender( new MyCustomAppender(blah) );

servlet 中针对“my.package”记录的任何内容现在都应该定向到您的自定义附加程序。

注意:SLF4J 通常不能很好地应对类加载器的摆弄。

关于java - Log4j 自定义 Appender 最初抛出 ClassNotFoundException?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17365329/

相关文章:

java - Wildfly 10 我可以在standalone.conf.bat中设置-Dspring.profiles.active吗?

java - 杰森没有出现

logging - 如何在Log4j2中追加多个追加器引用?

java - 我在哪里可以通过编程找到 log4j 日志文件的存储位置?

java - 超出范围异常

java - 在支持 UTF-8 的 Java 中解析 SQL 查询

java - 哪些插件用于在 Google Chrome 浏览器中查找定位器?

grails - Grails Log4j DSL 配置中的 Log4j 过滤器

java - Log4j2 无法使用 json 配置文件

java - log4j:如何使用 SocketAppender?