spring-projects / spring-framework

Spring Framework
https://spring.io/projects/spring-framework
Apache License 2.0
56.2k stars 37.96k forks source link

Consider replacing spring-jcl with regular Apache Commons Logging 1.3.0 #32459

Open garydgregory opened 6 months ago

garydgregory commented 6 months ago

As of Apache Commons Logging 1.3.0, the modulespring-jcl is redundant.

The module spring-jcl uses the Apache Commons Logging namespace and causes JPMS errors when used with the real Apache Commons Logging.

jhoeller commented 6 months ago

We can consider officially replacing spring-jcl with regular Apache Commons Logging 1.3.0 in Spring Framework 7, provided that we can get Log4J 2.x and SLF4J support without any extra dependencies. We don't insist on maintaining our own Commons Logging fork but we do need specific runtime characteristics and a configuration-free experience when putting Log4J 2.x or Logback on the classpath. It looks like Commons Logging 1.3.0 covers some new ground there indeed.

As for JPMS errors, this is arguably no worse than when using the jcl-over-slf4j or log4j-jcl bridges which spring-jcl was meant to replace. Just like those bridges, spring-jcl is designed as a replacement and not meant to be combined with the "real" Commons Logging. Such alternative implementations of the same namespace are not inherently in conflict with JPMS; the enforcement of only one such jar being present is even a JPMS feature that makes sense in such a scenario in particular.

FWIW, Commons Logging 1.3.0 should work fine with Spring Framework 5.x/6.x already when excluding spring-jcl and bringing commons-logging onto the classpath or module path instead. If this is not working for some reason, let us know.

ppkarwasz commented 6 months ago

@jhoeller,

Yes, with Commons Logging 1.3.0 provides SLF4J and Log4j API support out-of-the-box, using the same algorithm as spring-jcl (cf. apache/commons-logging#177):

Note: log4j-jcl never used the org.apache.commons.logging namespace but had commons-logging as dependency. With the release of Commons Logging 1.3.0 we deprecated log4j-jcl for removal in 3.x (cf. apache/logging-log4j2#2251).

Remark: Since Spring 7.x can introduce breaking changes, maybe Spring could migrate to Log4j API? The openrewrite/rewrite-logging-frameworks allows to do it already now.

hazendaz commented 6 months ago

Remark: Since Spring 7.x can introduce breaking changes, maybe Spring could migrate to Log4j API? The openrewrite/rewrite-logging-frameworks allows to do it already now.

Feels biased, some of us are biased the other way in using slf4j api. Now if one of those would simply win, it would be great. That didn't happen with log4j 2. Maybe 3 changes that. But then again slf4j has been extremely active now which is very unlike last few years.

Everything else sounds great and saw your request on slf4j as well. Less is better, we have far too many. It just needs to be clear from all parties but personally I too would like spring to choose one. IMO commons logging was entirely dead, its back and appears to mostly be trying to solve this issues more than anything else so I do applaud that work. Too many forks otherwise. But I think they could just use that and its really just spring-jcl redux so folks don't get pushed to one of the two that matter.

ppkarwasz commented 6 months ago

@hazendaz,

It is biased, but as you remark comparisons between SLF4J and Log4j API often are. These comparison often base on a false sense of continuity between Log4j 1.x and Log4j 2.x or a false sense of independence between SLF4J and its Logback implementation.

In reality Spring and most users just need parameterized logging and some lambda support. Maybe a third option will arise (Commons Logging 2.x?) that will only concentrate on releasing an interface instead of promoting its own implementation.

There will be no Log4j API 3.x for now, since Log4j Core 3.x will provide no breaking changes in the API (similarly as SLF4J 2.x didn't have any breaking changes from SLF4J 1.x).

jhoeller commented 6 months ago

For better or for worse, we have a lot of binary dependencies on the Commons Logging API across the portfolio, partly due to exposed protected Log logger fields, partly due to direct use. This includes third-party extensions and related projects that are not part of our release train.

We generally prefer to retain binary compatibility across major releases so that existing extensions and higher-level frameworks keep working when the core framework is being updated. This is particularly important for the Spring Framework 6->7 transition which is meant to be much easier to go through than 5->6 was with the jakarta namespace change etc. For that reason, we mean to hold on to the Commons Logging API if possible since it is all that we internally need within the framework. Application code is encouraged to use SLF4J or Log4J directly, but we internally do not need to be opinionated in that respect.

Commons Logging 1.3 sounds great for those purposes. If spring-jcl can be fully replaced there, I'll be happy to phase it out.