Hi Alex, On Wed, 7 Feb 2024 at 21:45, Alex Buckley <alex.buck...@oracle.com> wrote: > > in practice (`log4j-core`) code that depends > > on optional dependencies is in separate packages and accessed through > > reflection. > > This should be a runtime-only dependency, but many users do not care > > about the distinction between `compile` and `runtime` scope. > > Doesn't the POM of log4j-core express that some artifact ("an optional > dependency") has `runtime` scope / is `provided` ? Why is it relevant > that users of log4j-core don't care about the distinction between scopes?
The POM of `log4j-core` has its dependencies properly declared: they are either in the `provided` scope or in the `compile` scope with the `optional` flag. These artifacts are required during the compilation `log4j-core`, but their presence at runtime is optional. The scope problem appears, when another project (let's say `foo`) uses `log4j-core`. Since `log4j-core` is just an implementation of `log4j-api` and provides a ServiceLoader service that `log4j-api` consumes, 99% of the users could just declare `log4j-core` as runtime-only dependency of `foo`. This IMHO the correct usage and doesn't require any `requires` directives in the module descriptor of `foo`. Unfortunately the common practice is to add `log4j-core` in the default (compile) Maven scope of `foo`. Even Spring Boot Starter does it. If `foo` also declares `requires org.apache.logging.log4j.core;` in its module descriptor, users start having compilation errors, because Maven does not add the optional dependencies of `log4j-core` to the compiler module-path. Piotr PS: As I stated before, these problems appear in version 2.x of `log4j-core` that was retrofitted with JPMS. Version 3.x is designed with JPMS in mind, so only annotation dependencies are `static`.