Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Baffled by Java Logging Systems with Spring and Hibernate

WHen deploying my Spring / Hibernate application, I get the following warning related to logging:

log4j:WARN No appenders could be found for logger (org.springframework.web.context.ContextLoader).
log4j:WARN Please initialize the log4j system properly.

Surprising to me was the lack of information from a Google / SO search. The only thing relevant was this SO post Problem with Commons Logging / Log4j setup in spring webapp with tomcat 6

However, this is even beyond me. Can somebody clarify the logging systems in play here, or point me to a RECENT resource on the matter (there are some ancient google search results that don't really apply). Specifically, the issues I'm wrestling with are:

  • The distinction among commons-logging, log4j, slf4j and JCL. My understanding is that slf4j is a wrapper, while commons-logging and log4j are actual implementations. I don't know where JCL fits in.

  • How to configure logging for Spring. What does in the web.xml file, do i need a log4j.properties file or a log4j.xml file? Where does it go, in WEB-INF? Does anything go in my applicationContext.xml file? (sorry but I need to start from zero here).

  • I am using Hibernate in my project and including via Maven. It seems that Hibernate uses slf4j-simple. I have seen warnings saying that I can't have slf4j-simple and slf4j-log4j both on the classpath. I have not included slf4j-log4j as a dependency, but Hibernate must be including it. How do i solve this problem? Can I force Hibernate to use log4j instead?

Any help would be greatly appreciated. Thanks.


edit:

Thanks for all the answers so far. I am giving these suggestions a try. What about spring web-app specifically? I've seen examples of listeners and parameters and whatnot put into the web.xml file. Is this also required?

like image 205
D.C. Avatar asked Jan 21 '10 22:01

D.C.


People also ask

Which ways are used by the Log4j and Logback frameworks in Hibernate framework to support logging?

Log4j and Logback frameworks can be used in hibernate framework to support logging. There are two ways to perform logging using log4j: By log4j. xml file (or)

Which logging framework is best for Java?

One of the most popular solutions for the Java world is the Apache Log4j 2 framework. Maintained by the Apache Foundation, Log4j 2 is an improvement on the original Log4j, which was the most popular logging framework in Java for many years.


2 Answers

  • commons-logging and SLF4J are both API wrappers around other logging implementations. SLF4J is the more modern of the two, and rather more capable. Log4j is a logging implementation, and pretty much the defacto standard. JUL (short for java.util.logging) is the (generally awful) logging implementation that comes with the JRE. Another log implementation is logback, which is slowly gaining traction, but not at all widespread yet.
  • log4j.properties and log4j.xml are different ways of configuring log4j, both are equally valid. Which one you use is up to you, although some application servers dictate one or the other. Read the log4j manual to find out how to configure this.
  • If Hibernate uses SLF4J as its API, that's the choice of the Hibernate developers. However, you can choose which logging implementation SLF4J will delegate to. Again, read the slf4j manual to find out how to select your chosen implementation.

Yes, it's all rather confusing. Given an open choice, SLF4J and Logback is the most capable combination, but you usually don't get an open choice. Different frameworks (like Hibernate and Spring) will potentially use different logging APIs, usually commons-logging or SLF4J, but you can get all those APIs to eventually log to the same underlying implementation (usually log4j).

like image 72
skaffman Avatar answered Sep 30 '22 20:09

skaffman


  • The distinction among commons-logging, log4j, slf4j and JCL. My understanding is that slf4j is a wrapper, while commons-logging and log4j are actual implementations. I don't know where JCL fits in.

Jakarta Commons Logging (JCL) and Simple Logging Facade for Java SLF4J are both abstractions for various logging frameworks e.g. java.util.logging, log4j and logback, allowing the end user to plug in the desired logging framework at deployment time. Commons Logging is known to suffers from class loader problems which is what SLF4J tries to solve (SLF4J is known to be a cleaner library).

Having that said, the fact is that Spring uses Jakarta Commons Logging API (see Logging Dependencies in Spring): Spring is compiled against JCL and Spring makes JCL Log objects available for classes that extend Spring. The is actually the only mandatory external dependency in Spring. This choice has been made because many other frameworks where also using it (e.g. Struts). The idea was to avoid having to have multiple facade libraries on the class path when building applications ("A" for Spring, "B" for Struts, etc). It is however possible to replace JCL by SLF4J if you want to (SFL4J provides bindings to logging frameworks but also a "JCL to SLF4J" bridge). See the mentioned post Logging Dependencies in Spring for all the details.

  • How to configure logging for Spring. What does in the web.xml file, do i need a log4j.properties file or a log4j.xml file? Where does it go, in WEB-INF? Does anything go in my applicationContext.xml file? (sorry but I need to start from zero here).

To log, you have 1. to decide which implementation you want to use (java.util.logging, log4j or logback), 2. to put the chosen one on the classpath if required (java.util.logging is in Java SE so it doesn't require extra libraries) and 3. to configure it (by putting a config file on the classpath). If you choose to use log4j, just add its jar and a log4j.properties or a more fancy (but more verbose) log4j.xml (this is just another format for the configuration) to the classpath.

  • I am using Hibernate in my project and including via Maven. It seems that Hibernate uses slf4j-simple. I have seen warnings saying that I can't have slf4j-simple and slf4j-log4j both on the classpath. I have not included slf4j-log4j as a dependency, but Hibernate must be including it. How do i solve this problem? Can I force Hibernate to use log4j instead?

Hibernate utilizes Simple Logging Facade for Java (SLF4J) and, indeed, you can't have several bindings (e.g. slf4j-simple.jar and slf4j-logj12.jar) on the classpath at the same time. Here, you are very likely getting slf4j-simple.jar transitively from another dependency. To solve this problem, run mvn dependency:tree to figure out from where it's coming from and exclude it if required.

And by the way, in your case, I would configure Spring to use SLF4J as Hibernate is using it. Follow the steps in the link mentioned in the first paragraph for that. And I would use logback as logging framework (which the successor of log4j), this is where things happen now.

like image 36
Pascal Thivent Avatar answered Sep 30 '22 21:09

Pascal Thivent