Tags

, ,

JCL and slf4j are both wrapper for logging framework. Which means they need an actual logging framework for them to work. Currently, Spring 3 is using JCL, and we want to switch it to slf4j. Why? Because “slf4j does not suffer from class loader problems or memory leaks observed with JCL“. You may also find the explanation here. Even Spring Team blog mentioned that if they can switch back time, they would use slf4j instead of JCL.

And why need switch from java.util.logging to Logback? It is simply a matter of personal taste. I’d like to explore Logback a bit rather than using default logging framework.

For the detail comparison between various logging framework, you may refer to the following links:
http://stackoverflow.com/questions/354837/whats-up-with-logging-in-java
http://stackoverflow.com/questions/296150/what-are-the-best-practices-to-log-an-error

Enough said about the background on java logging framework, we should move on:

Objectives:

  1. To create a hello world application using Spring.
  2. To override the logging library of Spring so that instead of using Jakarta Commons Library (JCL) and java.util.logging, we use Simple Logging Facade for Java (slf4j) and Logback.

Prerequisites:

  1. Java Enterprise Edition (Java EE) SDK. Download and install.
  2. Eclipse for Java EE. Download and extract.
  3. Spring 3 framework library. Download.
  4. Basic understanding about Spring dependency injection. (Optional)
  5. Simple Logging Facade for Java (slf4j) library. Download.
  6. Logback library. Download.

Steps:
Create new “Java Project”.
Create a new folder called “lib” under the project.

Copy the following jar from Spring library to “lib” folder:
org.springframework.core-3.0.5.RELEASE.jar
org.springframework.beans-3.0.5.RELEASE.jar
org.springframework.context-3.0.5.RELEASE.jar
org.springframework.context.support-3.0.5.RELEASE.jar
org.springframework.asm-3.0.5.RELEASE.jar
org.springframework.expression-3.0.5.RELEASE.jar

Copy the following jar from slf4j library to “lib” folder:
slf4j-api-1.6.1.jar
jcl-over-slf4j-1.6.1.jar

Copy the following jar from Logback library to “lib” folder:
logback-core-0.9.27.jar
logback-classic-0.9.27.jar

Select the jars that you have put into “lib” folder. Right click and select the “Build Path” option and “Add to Build Path”. See the screenshot below.

Copy the following jar from slf4j library to “lib” folder:
slf4j-api-1.6.1.jar
jcl-over-slf4j-1.6.1.jar

Copy the following jar from Logback library to “lib” folder:
logback-core-0.9.27.jar
logback-classic-0.9.27.jar

Select the jars that you have put into “lib” folder. Right click and select the “Build Path” option and “Add to Build Path”. See the screenshot below.

Create new package “service” and “test” under source folder “src”.
Create a new interface “Message” in service package.

package service;

public interface Message {
 public String getHello();
}

Create a new class “StudentMessageImpl” that implement “Message” in service package.

package service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class StudentMessageImpl implements Message {
 private static final Logger logger = LoggerFactory
   .getLogger(StudentMessageImpl.class);

 @Override
 public String getHello() {
  logger.info("getHello - executed");
  return new String("Hello, Sir");
 }

}

Create a new JUnit Test Case Class in test package. If prompted to add JUnit library into build path, click OK.

package test;

import static org.junit.Assert.*;

import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import service.Message;

public class testMessage {
 Message msg = null;

 @Before
 public void setUp() throws Exception {
  ApplicationContext applicationContext = new
  ClassPathXmlApplicationContext("/application-context.xml");
  msg = (Message) applicationContext.getBean("message");
 }

 @Test
 public void testGetHello() {
  String helloStr = msg.getHello();
  assertTrue(helloStr.equals("Hello, Sir"));
 }

}

Create new source folder “resource” under the project.
Create a new xml file named “application-context.xml” under “resource”.

<?xml version="1.0" encoding="UTF-8"?>
 
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
     
    xsi:schemaLocation="

http://www.springframework.org/schema/beans


http://www.springframework.org/schema/beans/spring-beans-3.0.xsd


http://www.springframework.org/schema/context


http://www.springframework.org/schema/context/spring-context-3.0.xsd">

<bean id="message" class="service.StudentMessageImpl"/>
 
</beans>

Now you should be able to run the JUnit Test Case. Right click on your JUnit Test case code, and select “Run As” -> “JUnit Test”

In addition, you can also see the logs are printed to the console window.
You may filter these log so that only log with level >= info is printed out by doing the following steps:

Create a new xml file called “logback.xml” in “resource”.

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
 
 <appender name="STDOUT"
            class="ch.qos.logback.core.ConsoleAppender">
 
    <!-- encoders are assigned by default the type
         ch.qos.logback.classic.encoder.PatternLayoutEncoder -->
    <encoder>
   <pattern>
    %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
   </pattern>
    </encoder>
  </appender>
 
 <root level="INFO">
  <appender-ref ref="STDOUT" />
 </root>
 
</configuration>

If you run the Test Case again, you will see that only logs with trace level INFO is displayed in the console.

Last but not least, you can download the complete source code here.

About these ads