'How to create Java mixins: @Slf4j
I'm trying to create a Java mixin and use the @Slf4j annotation. However intellij shows an error @Slf4j is only legal for classes and enums.
import lombok.extern.slf4j.Slf4j;
@Slf4j
public interface Foo {
    default void foo() {
        log.info("Hello world");
    }
}
							
						Solution 1:[1]
If you want to use logging for the interface you could use a constant:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public interface Foo {
    Logger log = LoggerFactory.getLogger(Foo.class);
    default void foo() {
        log.info("Hello from Foo");
    }
}
If will have some implementation for this interface and you could overwrite a logger:
public class Bar implements Foo {
    Logger log = LoggerFactory.getLogger(Bar.class);
    public void bar() {
        log.info("Hello from Bar");
    }
}
With Lombok it could be done even simpler:
@Slf4j
class Bar implements Foo {
    public void bar() {
        log.info("Hello from Bar");
    }
}
Demo code:
public class LoggerDemo {
    public static void main(String[] args) {
        Bar bar = new Bar();
        bar.foo();
        bar.bar();
    }
}
Output:
20:40:48.010 [main] INFO demo.Foo - Hello from Foo 
20:40:48.014 [main] INFO demo.Bar - Hello from Bar
    					Solution 2:[2]
A simple way to solve the issue is to pass the logger to the foo() method:
import org.slf4j.Logger;
public interface Foo {
    default void foo(Logger log) {
        log.info("Hello world");
    }
}
Then use the @Slf4j annotation on classes that implement Foo:
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class Bar implements Foo {
    public void bar() {
        foo(log);
    }
}
    					Solution 3:[3]
One option is to add a getLogger method to the interface and require the implementations to implement that method. Then the interface can call that method.
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
public interface Foo {
    Logger getLogger();
    default void foo() {
        getLogger().info("Hello world");
    }
}
@Slf4j
public class Bar implements Foo {
    public void bar() {
        foo();
    }
    @Override
    public Logger getLogger() {
        return log;
    }
}
    					Solution 4:[4]
One option is to create an inner class with a static getLogger method.
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
public interface Foo {
    @Slf4j
    class Log {
        public static Logger getLogger() {
            return log;
        }
    }
    default void foo() {
        Log.getLogger().info("Hello world");
    }
}
    					Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source | 
|---|---|
| Solution 1 | |
| Solution 2 | Olivier | 
| Solution 3 | nanotek | 
| Solution 4 | nanotek | 
