ClassNotFoundException для обработчика java.util.logging в Maven tomcat7: запустить

Я следовал за часто задаваемыми вопросами BIRT относительно получения регистрации BIRT (которая, кажется, основана на java.util.logging) перенаправлен на log4j, который является стандартом моего проекта.

Впоследствии я сделал регистратор BIRT так:

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 выглядит следующим образом:

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

Я использую эту конфигурацию в трех местах:

  1. Eclipse -> отлично работает
  2. Tomcat -> отлично работает
  3. org.apache.tomcat.maven:tomcat7-maven-plugin:2.0 -> не работает

Последний выдает следующее сообщение об ошибке при запуске:

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, который я еще не совсем понял...

Я немного погуглил по этому поводу, нашел кучу "предполагаемых" решений, которые мне совсем не помогли, и на данный момент у меня нет идей. Ваша помощь будет высоко ценится.

1 ответ

С помощью трассировки стека он пытается загрузить обработчик, используя стандартный LogManager. Если вы имеете дело с любым загрузчиком классов, не видимым из системного загрузчика классов, вы столкнетесь с JDK-6448699. LogManager неправильно загружает обработчик журналов, а загрузка классов JMK-6878454 LogManager не соответствует рекомендациям Java EE.

Чтобы доказать, что ваш обработчик виден из системного пути класса, попробуйте следующий код:

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

Вы можете установить sun.misc.URLClassPath.debug системное свойство для true или используйте -verbose:class при запуске, чтобы получить больше отладочной информации о загрузке классов.

Должно быть похоже на следующее, где причина в том, что класс должен быть загружен до полной загрузки приложения:

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

Ваш класс должен быть виден модулю org.apache.log4j.
Попадание в ухо не помогает. Развертывание EAR изолировано для себя.

вы также можете

  • измените модуль org.apache.log4j, чтобы ваша банка также использовалась в качестве ресурса (скопируйте его туда)
  • или создайте новый модуль с вашими банками, а затем измените модуль log4j, чтобы он зависел от него.
Другие вопросы по тегам