Loggable: a simple log4j meta-library – Part 2

In a recent post I described the goal of my Loggable meta-library. If you haven’t read it yet, I suggest you to do it now.

What we are going to do now is analysing the second main component of the meta-library, the centralized controller Log.

How does it work

The main responsibility of the Log class is handling the logic behind the creation and returning of the Logger instance that the caller class should use. This logic, as we’ve already seen, is driven by the @Loggable annotation.

The Log class will have a single point of access: the public static method get(). Let’s look at if, briefly:

[java highlight=”9″][RAW]
public static Logger get() {
// Retrieve the StacKTraceElement of the caller method
StackTraceElement caller = getCaller();
// Retrieve the caller class
Class<?> clazz = getClass(caller);
// and its Loggable annotation instance
Loggable annotation = getAnnotation(clazz);

logger.debug("Returning a Logger for " + clazz.getSimpleName());

// Retrieve the suitable logger for the caller class and returns it
Logger suitableLogger = getLogger(annotation, clazz);
return suitableLogger;

This method does a precise series of things:

  1. Retrieves the stack trace element related to the caller method
  2. Retrieves the Class<?> instance which describes the caller class
  3. Reads the @Loggable annotation from the caller class
  4. Returns the suitable Logger instance, depending on the class and its @Loggable annotation definition

The whole code for this class will be available within the meta-library package, so I’ll focus just on the main private method: getLogger().

Bonus hint: as you can see, in my development environment the Log class makes a direct access to a Logger instance. This is strictly necessary because of recursions problems: if the Log class would call itself for logging purposes, this will generate a never-ending recursion stack. Try it, and try to explain why: this will be your homework for today 🙂 .
Continue reading

Loggable: a simple log4j meta-library – Part 1

If you work in a J2EE environment, you surely have (or at least will have) used the standard Apache log4j library almost once. This powerful and configurable logging library is commonly used throughout whole enterprise projects, for many reasons: debugging, testing, exception logging, tracing, application profiling, et cetera.

A common code that shows how to use a org.apache.log4j.Logger instance is the following:

[sourcecode language=”java” highlight=”6,9″][RAW]
package com.marzapower.test;

import org.apache.log4j.Logger;

public class MyClass {
private static final Logger logger = Logger.getLogger(MyClass.class);

public static void main(String… args) {
logger.debug("Hello World!");

As you can see, you define a private (visible only to the instances of this specific class) static (shared amongst all instances of the class) final (constant, not variable) Logger instance, and then you use it within the class. If you had another class, you should define a similar object into that class too. If you had a third, again, you’d define a Logger in that class too. And so on.

But when the number of the classes in your project grows, this approach easily becomes very frustrating. You are writing your code, and want to use a Logger, but you cannot do it directly unless you define the Logger instance for your classes. Again, if you are refactoring an existing class, that heavily uses the Logger instance for debugging purposes, and you delete all the Logger.debug() calls then … the classic yellow exclamation mark flag appears in your Eclipse editor: the private Logger instance defined is not being used anymore, so its declaration should be removed. And so on, you probably have faced a different (but still similar) problem before.

Continue reading