Ivan Alencar | 16 Jul 23:32

Circular Dependency through Appender

Hi,

I've created a log4j appender (by extending AppenderSkeleton) which uses a
component that depends on log4j. Naturally when I set log4j to use this
appender I get a circular dependency, because log4j needs the appender that
needs the component that needs the log4j that needs........... stack
overflow!

Component -----> log4j -----> Appender ----.
    ↑                                      |
    └--------------------------------------'

I can fix that issue just by instructing log4j (set threshold OFF for the
packages that contain logged classes in the component) to ignore the
component's classes that use log4j. Works, but it pollutes and adds
unnecessary complexity to the configuration file, moreover this is risky --
other programmers may not be aware of the circular dependency and will take
ages to figure out what is causing the problem.

To me, changing the logging logic in the component sounds good, but I don't
know exactly how to do that. Is there a way to specify which
appenders appenders used by the Logger instances in the component?

Thanks,
Ivan Z. Alencar
Michael Erskine | 17 Jul 12:12

RE: Circular Dependency through Appender

Ivan Alencar [mailto:ialencar <at> gmail.com] wrote:
> I've created a log4j appender (by extending AppenderSkeleton) which uses a
> component that depends on log4j.

If you can change the component then one technique I sometimes use is to pass in a Logger object which may be
null. Or I suppose one could temporarily set the static logger for that class to null while I'm accessing it
from an Appender. You can always programmatically disable the Logger for the component's class too with Logger.getLogger(whatever).setLevel()

Typically I try to write components that don't rely on any particular logging framework at runtime - keep it optional.

Regards,
Michael Erskine.
Ivan Alencar | 18 Jul 23:32

Re: Circular Dependency through Appender

Thanks Michael,

As I've implemented lot of logging in this component, I didn't feel like
wiping out all the nice logging just because of that circular dependency...

So I decided to ignore all settings from the log4j configuration file and
create a very specific Logger instance, programmatically.

Created a factory method which gives me a Logger instance, independent of
the root Logger, and has just one appender -- the ConsoleAppender.

*Instead of using *

private static Logger log = Logger.getLogger(MyClass.class);

*I use...*

private static Logger log = LoggingRescue.loggerFactory(MyClass.class);

*Fragment of the factory method...*

    public static Logger loggerFactory(Class clazz)
    {
        /** The new Logger */
        Logger log = null;

        // Gets the logger for the class
        log = Logger.getLogger(clazz);
        log.removeAllAppenders();
...
(Continue reading)


Gmane