问题
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:
- Eclipse --> works just fine
- Tomcat --> works just fine
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