I have the following sample code
Utility.myLogger
package Utility;
import org.apache.log4j.Logger;
class myLogger {
static Logger log = Logger.getLogger("com.mycompany")
Boolean logOn = true;
String TAG = this.class.toString();
def warn(String message) {
if (logOn) {
log.warn("$TAG: $message");
}
}
def error(String message) {
log.error("$TAG: $message")
}
}
Test Code
import Utility.myLogger;
class Parent {
myLogger l;
Closure warn;
Closure error;
Parent() {
this.l = new myLogger();
this.warn = l.&warn;
this.error = l.&error;
l.TAG = this.class.toString()
}
}
Parent p = new Parent();
p.error("Testing")
class Child extends Parent {
Child() {
super();
}
}
Child c = new Child();
c.error("Testing Child")
When I run this, I get two log messages, which is exactly what I expect:
2024-07-18T15:40:14,807 ERROR [mycompany]: class Parent: Testing
2024-07-18T15:40:14,816 ERROR [mycompany]: class Child: Testing Child
The call to p.error and c.error both have static type checking errors that “error(String)” is not found. The script runs correctly and I can continue to work without fixing this, but I would really like to understand why the compiler isn’t resolving the call to the error function.
Those closures are dynamic methods, and so if you are using @CompileStatic
or @TypeChecking
you will get errors from the usage of those methods. A more type safe way of doing what you want with less code would be to use @Delegate
annotation like so:
class Parent {
@Delegate MyLogger logger
Parent() {
logger = new MyLogger()
}
}
Now any method on MyLogger be available on Parent
through the @Delegate
annotation. No closures, or method refs needed. It will be compiled that way so it’s much faster too.
Furthermore, with Log4j you can configure it to output the class or name of the logger without the need to use the $TAG
method. If you want to add some contextual information to your log statements you also have Thread Context feature, Flow Tracing, Markers, etc. You could skip the MyLogger class all together, simplify your code, and get more powerful logging by adopting one of these features.