Maven tomcat7:run 中 java.util.logging 处理程序的 ClassNotFoundException

Maven tomcat7:run 中 java.util.logging 处理程序的 ClassNotFoundException

问题描述:

我已按照 BIRT 常见问题解答了解有关获取BIRT 的日志记录(似乎基于 java.util.logging)重定向到 log4j,这是我项目的标准.

I have followed the BIRT FAQ in regard to getting BIRT's logging (which seems to be based on java.util.logging) redirected to log4j, which is my project's standard.

我随后制作了一个 BIRT 记录器,如下所示:

I've subsequently made a BIRT logger like so:

public class BirtLogger extends Handler {
    private final Logger log = Logger.getLogger(BirtLogger.class);

    @Override
    public void publish(LogRecord record) {
        Level level = record.getLevel();
        String message = record.getMessage();
        if (Level.SEVERE.equals(level)) {
            log.fatal(message);
        }
        else if (Level.INFO.equals(level)) {
            log.info(message);
        }
        else if (Level.WARNING.equals(level)) {
            log.warn(message);
        }
    }
...

我的 logging.properties 如下所示:

And my logging.properties looks as follows:

#logging configuration for BIRT
handlers=com.totaalsoftware.fieldtracker.report.BirtLogger

我在三个地方使用这个配置:

I am using this configuration in three places:

  1. Eclipse --> 工作正常
  2. Tomcat --> 工作正常
  3. org.apache.tomcat.maven:tomcat7-maven-plugin:2.0 --> 不工作
  1. Eclipse --> works just fine
  2. Tomcat --> works just fine
  3. org.apache.tomcat.maven:tomcat7-maven-plugin:2.0 --> not working

后者在启动时给出以下错误信息:

The latter gives the following error message upon startup:

java.lang.ClassNotFoundException: com.totaalsoftware.fieldtracker.report.BirtLogger
java.lang.ClassNotFoundException: com.totaalsoftware.fieldtracker.report.BirtLogger
        at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:423)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
        at java.util.logging.LogManager$3.run(LogManager.java:418)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.util.logging.LogManager.loadLoggerHandlers(LogManager.java:405)
        at java.util.logging.LogManager.initializeGlobalHandlers(LogManager.java:1076)
        at java.util.logging.LogManager.access$1100(LogManager.java:148)
        at java.util.logging.LogManager$RootLogger.getHandlers(LogManager.java:1159)
        at java.util.logging.Logger.log(Logger.java:521)
        at java.util.logging.Logger.doLog(Logger.java:543)
        at java.util.logging.Logger.logp(Logger.java:659)
        at org.apache.juli.logging.DirectJDKLog.log(DirectJDKLog.java:183)
        at org.apache.juli.logging.DirectJDKLog.info(DirectJDKLog.java:126)
        at org.apache.catalina.core.ApplicationContext.log(ApplicationContext.java:710)
        at org.apache.catalina.core.ApplicationContextFacade.log(ApplicationContextFacade.java:298)
        at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:442)
        at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:133)
        at javax.servlet.GenericServlet.init(GenericServlet.java:160)
        at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1266)
        at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1185)
        at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1080)
        at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:5027)
        at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5314)
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
        at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559)
        at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549)
        at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
        at java.util.concurrent.FutureTask.run(FutureTask.java:166)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
        at java.lang.Thread.run(Thread.java:722)

然而,我确实相信这个​​缺失"的类在应用程序的类路径上.但是对于tomcat7 Maven 插件可能有一些我还没有完全掌握的类加载特性......

I do believe however, that this "missing" class is on the application's classpath. But there may be some classloading specialties for the tomcat7 Maven plugin that I haven't quite grasped yet...

我为此在谷歌上搜索了很多,找到了一堆假设"的解决方案,但对我没有任何帮助,此时我已经没有想法了.非常感谢您的帮助.

I googled quite a bit for this, found a bunch of "supposed" solutions that didn't help me at all, and I'm out of ideas at this point. Your help would be much appreciated.

从堆栈跟踪来看,它正在尝试使用标准 LogManager 加载处理程序.如果您正在处理从 系统类加载器 你会遇到JDK-6448699 LogManager 没有正确加载日志处理程序JDK-6878454 LogManager 类加载与 Java EE 最佳实践不一致.

From the stacktrace, it is trying to load the handler using the standard LogManager. If you are dealing with any classloader not visible from system class loader you'll run into JDK-6448699 LogManager does not load log handler correctly and JDK-6878454 LogManager class loading inconsistent with Java EE best practices.

要证明您的处理程序在系统类路径中可见,请尝试以下代码:

To prove your handler is visible from the system class path try the following code:

Class.forName("com.totaalsoftware.fieldtracker.report.BirtLogger", true, ClassLoader.getSystemClassLoader());

您可以将 sun.misc.URLClassPath.debug 系统属性设置为 true 或在启动时使用 -verbose:class 来获取更多关于类加载的调试信息.

You can set the sun.misc.URLClassPath.debug system property to true or use the -verbose:class on launch to get some more debug information on classloading.