ClassNotFoundException for java.util.logging handler in Maven tomcat7:run

南楼画角 提交于 2020-07-10 11:47:59

问题


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.

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);
        }
    }
...

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 --> 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)

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.


回答1:


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());

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.




回答2:


should be similar to the following, where the cause is, that the class has to be loaded before the application is completely loaded:

https://developer.jboss.org/message/976425#976425

Your class needs to be visible to org.apache.log4j module.
Having it in your ear doesn't help. EAR deployment is isolated for itself.

you can either

  • modify the org.apache.log4j module to also have your jar as resource (copy it in there)
  • or create new module with your jars and than modify log4j module to have dependency to it.


来源:https://stackoverflow.com/questions/16501138/classnotfoundexception-for-java-util-logging-handler-in-maven-tomcat7run

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!