[MNG-7532] Log shouldn't have been deprecated so ensure it is not - #793
Conversation
|
I still don't understand why we need a wrapper around a facade... |
|
@michael-o I don't have all the threads handy but we have several dev@ threads explaining it has several technical pitfalls (the way the API loads the impl - v1 or v2) and that we don't want to bind ourselves to an implementation we can't sustain in time. This PR just avoids to have to redefine yet another package and API for plugin (work Guillaume is doing) since we already have it and can enhance it with |
I see, what I would like to avoid is to add features to this wrapper which will duplicate SLF4J at the end. We have this: Plexus Logging. |
|
@michael-o right but it is not clear what we do of plexus - we are between being based on it and dropping it. Personally I tend to think we should rely on the abstraction we want to expose long term in a very stable way so either JUL (which can be used as an abstraction) or an org.apache.maven.somethingLogging but if we import plexus @asf it sounds like another valid option. |
Do you expect SLF4J 2.x not to live 10 years? |
|
I'd be interested to head @ceki's opinion on this. |
I expect it to not be usable within 5 years at least due to the current usage of 1.x and SLF4J is a good example of why we shouldnt rely on a 3rd party for our own API (once again, point is used by users), it broke several times and we can't help. |
|
The client facing API of SLF4J is stable and has been stable since version 1.0. You can compile an application using the API in SLF4J 1.0 (released in 2005) and it will run just fine with SLF4J version 2.0 on the classpath. As for Maven creating its own logging API, there is a FAQ entry treating this question. Anyway, thank you all for your awesome work on Maven. |
Not really 1.5->1.6 were not compat for ex (LocationAwareLogger#log, MessageFormatter, etc...). It hurt several apps already. It is really not "is slf4j bad" topic - in particular since it is fine to use it in @apache/maven core modules - but simply a design issue (we could workaround technical details if we would like to use it on a pure technical side), we should own our API to ensure mojo and extensions are reliable in time and not highly unstable (like gradle had been and was forced to introduce the wrapper to workaround it). |
|
@rmannibucau Since you mention As for stability, perhaps Maven has a higher standard regarding API compatibility than SLF4J, as Maven really shines in that regard. |
You are mostly talking about impl, not API not. For the plugin dev.SLF4J simply works. |
No @michael-o this is 100% the API sadly. We went through that several times on several apache projects as mentionned and as mentionned it is not only due to slf4j quality but also our own design so let's just do our homework and align on the dev@ discussion our code. @ceki the people I saw complaining about it was not this one so guess it was not alone bitten by this change. I also think the "lifecycles" of both projects are not aligned there and to be honest, exposing SLF4J creates several issues in MOJO - once again, nothing linked to SLF4J, 100% linked to Maven classloading and design even if for the good - so in terms of design and technically Maven should really aim at abstracting it even if I agree with Michael, it means another abstraction but it is highly justified by years of experience and no real good fixes without it as proven by the past. |
|
it's incomplete - we would also update maven site and say that slf4j introduced for logging in 3.1 is now obsolete? |
|
@slachiewicz there are some discussions about the related pages since there was never a consensus nor a consistent update of that on our website. |
It seems to me that https://maven.apache.org/maven-logging.html is mostly about the logging system in general, not really the api to use for mojos. |
|
yes, slf4j was never validated for mojo, there was an excess of enthusiasm in the javadoc but it was never validated nor ack-ed by the community so no big deal. |
|
For Maven plugins we can provide own API or abstraction ... but users can use third party library for implementing plugin code. We can not expect that all code in plugins only use Maven and JDK API, thirt party library used in plugins code can uses any logging framework. It should not be important what logging framework is used in Maven core. So I'm for not providing next abstraction but allow users use some of commonly available frameworks, like spring-boot does: https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.logging |
Sure and we comply to that, only thing is that end user can only expect maven logging framework to be integrated with maven ecosystem (think CI and maven customizations) so if the plugin provider wants something well integrated it has to use that.
Probably a good wish but factually it is.
Good wish too but there are several cases which are not trivial. Personally I see it as limitations when deployed inside maven and most plugins have work arounds for that so all good, but we are not neutral enough (as the JVM is) to support anything. Not sure about the spring reference but it is the same, they work in some env but not always and this is ok. The only thing maven guarantees is that the plugin API will go through maven logging system so if integration is customized it will get the logs, anything else is not guaranteed - except JUL by construction indeed. |
If we:
If course, libraries that do setup specifically a logging framework, it will most certainly not be integrated, but we can't do much about that. |
|
Then we can also think how to support slf4j 1 and 2. More and more libs switch to v2 |
Afaik, the client api is compatible, if maven exports slf4j 2.x and provides an implementation, client should be fine. |
|
@slachiewicz if we switch we should just go to JUL IMHO (see the list for details) but not sure it would be for v4, hopefully v5. Anyway, does not change anything to the fact we don't want to show our impl to end users since one feature we provide is the hability to integrator to handle it as they want. All log libs have pitfalls and we can't make everything working (typically there are some cases with some bridge which will fail), so let's stay simple and 1. drop slf4j from consumers view in code, 2. if we need to change current impl move to JUL which enables to be dep free, abstract any impl (several asf projects do like cxf) and work in all integrator env without hacks. |
|
For Maven 5 sounds good, hope we someone will deliver new better API and bridges to existing frameworks. |
|
So the problem with exporting the slf4j unmodified is that things may break if a plugin depends on a library which itself imposes constraints on the slf4j binding used (by configuring it programmatically for example). |
|
@gnodet let's ignore a second the classloading errors and take a simple functional case: you want logger X to be logged particularly and the app knows the provider it uses so can configure it directly - this is a common case as we discussed on slack. I'll use JUL binding for the example but it is not rare it is logback or log4j2 too. Here is a simple mojo showing it: <dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.36</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-jdk14</artifactId>
<version>1.7.36</version>
</dependency>@Mojo(name = "demo", defaultPhase = NONE)
public class MyMojo extends AbstractMojo {
@Override
public void execute() {
run();
}
private void run() {
final var loggerName = getClass().getName();
final var logger = Logger.getLogger(loggerName);
final var delegate = Logger.getLogger("");
logger.addHandler(new Handler() {
@Override
public void publish(final LogRecord record) { // just a hack to get console logger but not close it
delegate.getHandlers()[0].publish(record);
}
@Override
public void flush() {
// no-op
}
@Override
public void close() throws SecurityException {
// no-op
}
});
LoggerFactory.getLogger(loggerName)
.info("I am here");
}
}Indeed you have to assume the logging configuration is not part of the execute method but a transitive one - a bit like spring logging system. Running this mojo we get: Which is not really the expectation: So we can see that the format is wrong - which can be an issue for downside parsing, the plugin will not enable to test grokking for ex, but the setup is not even respected in maven (the duplicated log is an intentional coding bug but does not surface with maven). Worse, maven ignores So I really think we should give the control of that to mojo:
The last trick we'll see - since we spoke of slf4j 2 - is that it does not use its classloading custom lookup anymore for the logger factory but a plain ServiceLoader JPMS based so ClassRealm is not ready for that at all. Guess we'll need to work on that at some point so I don't think we'll need a workaround in our SLF4J impl to delegate to plugin impl if any but means we will still have some issues with slf4j. Hope it helps |
|
Up, seems we are still un a broken state where we say to use slf4j for plugins and I didn't find the mvn4 API (pretty sure you did something @gnodet but didnt see it in mvn4 branch). |
|
@cstamas please just check out "slf4j plugin api" in your mailbox and check the related 5-6 threads, there is NO consensus in the community about using slf4j in the api so this is not something we can promote. Agree the community is split - also why we must not promote slf4j yet for plugins.
So not sure what is really to discuss to be honest, look like you fight for an already finished battle 🤔 |
|
IIRC, the example that was given by @rmannibucau was when a library actually requires a given implementation of slf4j. This happens sometimes when a library is configuring the underlying implementation programmatically. Proposal for v4 plugins. In those case, I'm not sure what happens if we expose even the slf4j implementation. I've also hit some problems with plexus logger which is now hidden, so it needs to be configured manually: |
|
This is a Draculan discussion. It sucks out everything. |
|
@gnodet well code was shared but you can review https://github.com/rmannibucau/mojo-logging-demo which is only about 2 cases (but there are more like using alpha version of slf4j or the opposite). Overall the outcome of discussions is that even if it would be simpler to leak all our internals (it is not only logging there), it is not really possible because we adopted an isolated architecture (realms) cause plugins have to do their stuff and we should just support it so we should isolated everything but the mvn4 api (status quo for mvn3). side note: if this is no more assumed by most of community - I don't think it is the case but just highlighting what it means - we would have to drop the classrealm which wouldn't make much sense anymore and just request any plugin writer to fork for their work which rely on any other dependency than the ones we provide - don't think it is good but it is ultimately what we mean if we leak more and more. |
SLF4j api has been exported for more than 13 years, I haven't traced back to the very beginning though... |
|
@gnodet well yes and no, original export was partial and broken but makes 6-7 years it is bothering, but anyway does not change we don't want it to surface as a maven provided API from the previous discussions so deprecated was a missed 3 years ago IMHO. Until we get maven 4 "1.0.0" we should just deprecate Log and then switch to the provider Log of mvn 4 API, looks quite straight forward to me as path, no? |
|
Resolve #8918 |
|
Resolve #8918 |
|
Is this still in play or should we close this PR? |
|
̀Use SLF4J directly |
gnodet
left a comment
There was a problem hiding this comment.
AI Code Review — PR #793
Verdict: 💬 COMMENT — Needs rebase
The intent is reasonable: un-deprecating Log, SystemStreamLog, Mojo.getLog()/setLog(), and AbstractMojo.getLog()/setLog() in the plugin API. The argument that the compat layer should remain the supported path for Maven 3.x plugins (and that deprecation directs users to SLF4J when the real migration path is the new Maven 4 API) has merit.
However, the PR is nearly 4 years old and cannot be merged in its current state.
Findings
| # | Severity | File | Details |
|---|---|---|---|
| 1 | 🔴 High | All 4 files | Stale paths — All modified files (maven-plugin-api/src/main/java/...) were moved to compat/maven-plugin-api/src/main/java/... by MNG-8346. The old paths return 404 on current master. Merge state is CONFLICTING. |
Context
- The code change itself is safe — removing
@Deprecatedand@deprecatedis backward-compatible. No functional behavior changes. - Community discussion was inconclusive — michael-o, slachiewicz, and slawekjaranowski all expressed reservations. gnodet approved but the PR was never merged.
- Maven 4 context has evolved — The new
org.apache.maven.api.plugin.Mojouses SLF4J and has noLogconcept. The compat layer exists so Maven 3.x plugins continue to work. WhetherLogshould remain deprecated in the compat module is worth revisiting given the current state of Maven 4.
Recommendation
If this is still desired: (1) rebase onto current master targeting compat/maven-plugin-api/... paths, and (2) re-open the community discussion on dev@maven given that the Maven 4 landscape has changed significantly since 2022.
This review was generated by an AI agent and may contain inaccuracies. Please verify all suggestions before applying.
Claude Code on behalf of Guillaume Nodet
Reviewed 3 PRs: apache#2023 (COMMENT), apache#1538 (COMMENT), apache#793 (COMMENT). 27 total reviews posted. ~32 PRs remaining. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
gnodet
left a comment
There was a problem hiding this comment.
Code Review
This nearly 4-year-old PR cannot merge in its current form.
1. File paths have moved (high)
All 4 files were relocated by MNG-8346 from maven-plugin-api/src/main/java/... to compat/maven-plugin-api/src/main/java/.... The PR targets paths that no longer exist. Merge state is CONFLICTING.
2. Deprecation still present (medium)
The @Deprecated annotations and @deprecated Javadoc tags ("Use SLF4J directly") are still present in the current code at the new paths — the PR's intended changes were never applied.
3. Maven 4 changes the framing (medium)
Maven 4 now has a dedicated org.apache.maven.api.plugin.Log interface (@Experimental, @since 4.0.0) that serves as the forward-looking replacement. The compat module's Log is intentionally a backward-compatibility shim for Maven 3 plugins. This changes the rationale: keeping the compat types deprecated may be architecturally correct since the compat module's purpose is backward compatibility, and the new API exists for Maven 4 plugins.
Recommendation
If this change is still desired, it would need: (1) a rebase onto current master targeting compat/maven-plugin-api/... paths, (2) renewed community consensus on dev@maven given the Maven 4 API now exists, and (3) consideration of whether deprecation in the compat module is the correct signal.
This review was generated by an AI agent and may contain inaccuracies. Please verify all suggestions before applying.
Claude Code on behalf of gnodet
|
@gnodet do we consider it is fixed in maven 4 and "dont care" in maven 3 land or should i rebase? |
Actually, it's only partially fixed in Maven 4 I think, see I'd rather remove it and enforce the use of |
|
ok so rebasing now |
gnodet
left a comment
There was a problem hiding this comment.
The rebase resolved the primary blocker — all 4 files now target the correct compat/maven-plugin-api/... paths (moved by MNG-8346), and the PR is now mergeable.
The diff is semantically identical to the original commit. It consistently removes all @Deprecated and @deprecated markers from Log (interface), SystemStreamLog (class), Mojo.getLog()/setLog() (interface methods), and AbstractMojo.getLog()/setLog() (implementation). No deprecation markers are left behind inconsistently.
The Maven 4 API now has its own org.apache.maven.api.plugin.Log and a clean Mojo interface — this supports un-deprecating the compat types since the migration path for plugin authors is to the new Maven 4 API, not to SLF4J directly.
Note: CI checks were still pending at review time — merge should wait until they pass.
This review was generated by an AI agent and may contain inaccuracies. Please verify all suggestions before applying.
Claude Code on behalf of gnodet
|
@rmannibucau Please assign appropriate label to PR according to the type of change. |

Follow up of dev discussions and to avoid to reduplicate the API in the new plugin API, restoring
Logofficial status.Following this checklist to help us incorporate your
contribution quickly and easily:
for the change (usually before you start working on it). Trivial changes like typos do not
require a JIRA issue. Your pull request should address just this issue, without
pulling in other changes.
[MNG-XXX] SUMMARY, where you replaceMNG-XXXand
SUMMARYwith the appropriate JIRA issue. Best practice is to use the JIRA issuetitle in the pull request title and in the first line of the commit message.
mvn clean verifyto make sure basic checks pass. A more thorough check willbe performed on your pull request automatically.