JUL Adapter not working for Jersey
java.util.logging.LogManager
class gets initialized when web application container like tomcat
, gretty
gets started. At the time of loading (in static block
), this class checks for the value of java.util.logging.manager
system property and create the Logger
accordingly. Once initialized, this class never gets initialized again.
So, for a web application, setting this system property through web application code would be too late.
One possible solution is to pass this system property value through VM arguments
to the application container -
-Djava.util.logging.manager="org.apache.logging.log4j.jul.LogManager"
In this situation, you have to provide log4j
jars and configuration file at the time of starting container so that org.apache.logging.log4j.jul.LogManager
can be loaded through System ClassLoader
.
For tomcat, following 3 jars you must load along with bootstrap.jar
(tomcat startup), tomcat-juli.jar
(logging) to make it work -
log4j-jul
log4j-api
log4j-core
Similar approach needs to be used for other container also.
If you are not able or allowed to change the configuration of the container, here's an alternative solution that worked for me.
When the context is initialised, remove all the handlers that a JUL logger has, then add your own custom handler where you can use your preferred logging framework.
Here's an example:
import java.util.logging.Handler;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
@WebListener
public class ContextInitializer implements ServletContextListener {
Logger logger = Logger.getLogger("");
static final org.apache.logging.log4j.Logger log4jLogger = LogManager.getLogger();
@Override
public void contextInitialized(ServletContextEvent sce) {
for (Handler hanlder : logger.getHandlers()) {
logger.removeHandler(hanlder);
}
logger.addHandler(new CustomHandler());
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("Context destroyed.");
}
private static class CustomHandler extends Handler {
@Override
public void publish(LogRecord record) {
log4jLogger.log(CustomHandler.julToLog4jLevel(record.getLevel()), record.getMessage(), record.getThrown());
}
/**
* Converts the logging level according to [default level conversions](https://logging.apache.org/log4j/2.0/log4j-jul/index.html)
*/
private static Level julToLog4jLevel(java.util.logging.Level level) {
if (level == java.util.logging.Level.WARNING) {
return Level.WARN;
} else if (level == java.util.logging.Level.SEVERE) {
return Level.ERROR;
} else if (level == java.util.logging.Level.INFO) {
return Level.INFO;
} else if (level == java.util.logging.Level.FINE) {
return Level.DEBUG;
} else if (level == java.util.logging.Level.FINER) {
return Level.TRACE;
} else if (level == java.util.logging.Level.FINEST) {
return Level.ALL;
}
return null;
}
@Override
public void flush() {
}
@Override
public void close() throws SecurityException {
}
}
}