0

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.

Sander Verhagen
  • 8,540
  • 4
  • 41
  • 63
  • Did you really verify that the logger is on the CP? – Michael-O May 11 '13 at 22:13
  • Yes, I can instantiate it from other classes in my application and I verified the correct spelling of its fully-qualified name. Also, this same configuration is working in Eclipse, and more importantly: when deploying the WAR to an actual Tomcat. – Sander Verhagen May 12 '13 at 05:56
  • This seemed like a simple-enough question, hence I'm somewhat puzzled that no one has any pointers for me. Any further assistance will be much-appreciated. – Sander Verhagen May 21 '13 at 03:34

2 Answers2

2

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.

jmehrens
  • 10,580
  • 1
  • 38
  • 47
  • As I mentioned, it's on the application's classpath. But you're right, it's not on the system classpath, as tested per your suggestion. Do you have any ideas how to *get* it on the system classpath per Maven configuration or programmatically? – Sander Verhagen Nov 24 '13 at 07:49
  • Not off the top of my head. Check the Maven documentation. A wrong package/class name would also throw this type of error. Double check your config file. – jmehrens Nov 24 '13 at 16:00
0

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.
Andreas Covidiot
  • 4,286
  • 5
  • 51
  • 96