Thanks, We were just discussing this in our video call last week. It was also pointed out that there are advantages to Log4j using its own Supplier although I cannot remember what they were.
Of course, the Log4j Supplier could be modified to extend j.u.f.Supplier, although I don’t know what the point of that would be. Adding new methods that use j.u.f.Supplier almost certainly would just create a mess and require casting all over the place. Ralph > On May 12, 2022, at 9:00 AM, Chris Hegarty <chegar...@gmail.com> wrote: > > Hi, > > I want to pick up an old thread [1], for which I cannot find a conclusion. > Apologies if this has already been discussed, but I cannot find it anywhere > (and I have looked!). > > It relates to the potential of dropping o.a.l.log4j.util.Supplier in favour > of the standard j.u.f.Supplier. I think that such is a great idea, but I want > to ensure that some details are not overlooked. > > log4j.Supplier shows up in public API methods like, say, > Logger.info(Supplier<?>). If this, and others, were migrated to say, > Logger.info(util.Supplier<?>), then this would be a, > > - source compatible change, but a > - binary incompatible change > > Source compatible, since type inference will infer the similarly shaped > util.Supplier method variant when recompiling the consuming call sites > against the new method signature. > > Binary incompatible, since existing classes compiled against the existing > info(log4j.Supplier) will have method descriptors in their byte code > referencing the log4j.Supplier signature variant, which will not be > resolvable at runtime. > > For clarity, here is a brief, somewhat contrived, minimal example: > > // Fake Logger interface > $ cat Logger.java > public interface Logger { > void info(org.apache.logging.log4j.util.Supplier<?> messageSupplier); > } > > // Fake LogManager: factory for loggers that log to stdout > $ cat LogManager.java > public class LogManager { > public static Logger getLogger() { > return new Logger() { > @Override > public void info(org.apache.logging.log4j.util.Supplier<?> > messageSupplier) { > System.out.println(messageSupplier.get()); > } > }; > } > } > > // Compile these > $ javac -cp log4j-api-2.17.1.jar Logger.java LogManager.java > > > // Minimal app that does some logging > $ cat Main.java > public class Main { > public static void main(String... args) { > LogManager.getLogger().info(() -> "log msg"); > } > } > > $ javac -cp log4j-api-2.17.1.jar:. Main.java > $ java -cp log4j-api-2.17.1.jar:. Main > log msg > > > // Now migrate the logging framework to util.Supplier > > $ cat Logger.java > public interface Logger { > void info(java.util.function.Supplier<?> messageSupplier); > } > $ cat LogManager.java > public class LogManager { > public static Logger getLogger() { > return new Logger() { > @Override > public void info(java.util.function.Supplier<?> messageSupplier) { > System.out.println(messageSupplier.get()); > } > }; > } > } > > // recompile the logging framework > $ javac Logger.java LogManager.java > > // Now rerun the app code (without recompiling) - binary incompatible > > $ java -cp log4j-api-2.17.1.jar:. Main > Exception in thread "main" java.lang.NoSuchMethodError: 'void > Logger.info(org.apache.logging.log4j.util.Supplier)' > at Main.main(Main.java:4) > > // Recompile the app code - source compatible > $ javac Main.java > $ java Main > log msg > > -Chris. > > [1] https://www.mail-archive.com/dev@logging.apache.org/msg07967.html >