Hi Alan, On Wed, 31 Jan 2024 at 16:41, Alan Bateman <alan.bate...@oracle.com> wrote: > On 31/01/2024 07:47, Piotr P. Karwasz wrote: > There is however a third option allowed: > > ```java > module foo { > requires static transitive bar; > } > ``` > > It may be surprising but they do work together. If bar is resolved then foo > will read bar. If there is another module baz that requires foo (and doesn't > explicitly require bar) then baz will read foo, and if bar is resolved, then > baz will read bar.
Thank you for the explanation. Effectively as long as there is no path of `requires transitive` from a root module to `foo`, the `bar module is optional. > We often end up with such directives, when using the > `bnd-maven-plugin`, which maps the OSGi `resolution:=optional` > directive to `static` and the `uses:=...` directive to `transitive`. > If we mark a package as optional, but the package uses public types > from `bar`, we end up with `static transitive`. > > Is this a bug of the plugin or does `static transitive` have a meaning? > > I think it's more of a case that it is fragile for modules like foo to have > bar types foo API signatures. `requires static` is okay for things like > annotations with a retention policy of "source" but going beyond that means > giving up a bit on reliable configuration. In the example, foo probably has a > reflection guard and is careful in their use of bar types. However, foo's > user if baz and the maintainers of baz are unaware of these shenanigans. This > creates a risk that baz code will get a CNFE at runtime. Yes, in the example and 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. If a user declares `log4j-core` as compile dependency and adds `requires org.apache.logging.log4j.core` to their module descriptor, the `requires static transitive` directives will cause compilation errors, since the minimal compilation time resolution requires all transitive dependencies of direct dependencies. That is why we manually remove the `transitive` keyword from those dependencies. Would it be wiser not to export packages that depend on optional dependencies? Piotr PS: We are facing the problems above with the legacy 2.x version, which predates JPMS. In the new 3.x version we split the code with optional dependencies into separate artifacts.