<div dir="ltr"><i>> <span style="color:rgb(23,43,77);font-family:"DejaVu Sans",sans-serif;font-size:14px">really a request to allow more usage of `requires static` and specifically to allow `provides p.S with ...`<span class="gmail-Apple-converted-space"> </span></span></i><div><span style="color:rgb(23,43,77);font-family:"DejaVu Sans",sans-serif;font-size:14px"><span class="gmail-Apple-converted-space"><br></span></span></div><div><span style="color:rgb(23,43,77);font-family:"DejaVu Sans",sans-serif;font-size:14px"><span class="gmail-Apple-converted-space">Yes, that's my case.</span></span></div><div><span style="color:rgb(23,43,77);font-family:"DejaVu Sans",sans-serif;font-size:14px"><span class="gmail-Apple-converted-space"><br></span></span></div><div><span style="color:rgb(23,43,77);font-family:"DejaVu Sans",sans-serif;font-size:14px"><span class="gmail-Apple-converted-space"><br></span></span></div><div><i><span style="color:rgb(23,43,77);font-family:"DejaVu Sans",sans-serif;font-size:14px"><span class="gmail-Apple-converted-space">> </span></span><span style="color:rgb(23,43,77);font-family:"DejaVu Sans",sans-serif;font-size:14px">If Foo isn't available, then (so the thinking goes) the `provides` is moot, and the implementation's dependence on Foo should be ignored.</span></i></div><div><span style="color:rgb(23,43,77);font-family:"DejaVu Sans",sans-serif;font-size:14px"><br></span></div><div><span style="color:rgb(23,43,77);font-family:"DejaVu Sans",sans-serif;font-size:14px">Yes!!.</span></div><div><span style="color:rgb(23,43,77);font-family:"DejaVu Sans",sans-serif;font-size:14px"><br></span></div><div><span style="color:rgb(23,43,77);font-family:"DejaVu Sans",sans-serif;font-size:14px"><br></span></div><div><i><span style="color:rgb(23,43,77);font-family:"DejaVu Sans",sans-serif;font-size:14px">> </span><span style="color:rgb(23,43,77);font-family:"DejaVu Sans",sans-serif;font-size:14px">However, this desire is not clearly communicated by the implementation module expressing `requires static <interface-module>` -- the interface-module could export many packages, not just one package containing one interface Foo, so the `requires static` is not flagging anything about the service interface per se.</span></i></div><div><span style="color:rgb(23,43,77);font-family:"DejaVu Sans",sans-serif;font-size:14px"><br></span></div><div><span style="color:rgb(23,43,77);font-family:"DejaVu Sans",sans-serif;font-size:14px">Hmmm, my thinking was going the other direction. With the provides  <i>p.S</i> uses ...  the p.S is <b><i>ONLY</i></b> visible to the module at compile time via the requires <b style="font-style:italic">static </b>[so at compile time we can infer that the p.S type is optional and might not exist at runtime based on the requires <i>static</i>].</span></div><div><span style="color:rgb(23,43,77);font-family:"DejaVu Sans",sans-serif;font-size:14px"><br></span></div><div><span style="color:rgb(23,43,77);font-family:"DejaVu Sans",sans-serif;font-size:14px"><br></span></div><div><i><span style="color:rgb(23,43,77);font-family:"DejaVu Sans",sans-serif;font-size:14px">> </span><span style="color:rgb(23,43,77);font-family:"DejaVu Sans",sans-serif;font-size:14px">Optional dependencies are meant to support annotations and other limited use cases.</span></i></div><div><span style="color:rgb(23,43,77);font-family:"DejaVu Sans",sans-serif;font-size:14px"><br></span></div><div><span style="color:rgb(23,43,77);font-family:"DejaVu Sans",sans-serif;font-size:14px">Ok ... umm.</span></div><div><span style="color:rgb(23,43,77);font-family:"DejaVu Sans",sans-serif;font-size:14px"><br></span></div><div><span style="color:rgb(23,43,77);font-family:"DejaVu Sans",sans-serif;font-size:14px"><br></span></div><div><i><span style="color:rgb(23,43,77);font-family:"DejaVu Sans",sans-serif;font-size:14px">> </span><span style="color:rgb(23,43,77);font-family:"DejaVu Sans",sans-serif;font-size:14px">All of this boils down to: if the implementation module says `provides`, then is it reasonable to consider that ServiceLoader is the *only* vector by which the implementation class will be instantiated? If yes, then module resolution should perhaps be tolerant of a `provides` that specifies a missing service interface. If no ...</span></i></div><div><span style="color:rgb(23,43,77);font-family:"DejaVu Sans",sans-serif;font-size:14px"><br></span></div><div><span style="color:rgb(23,43,77);font-family:"DejaVu Sans",sans-serif;font-size:14px">Yes, I follow this and agree.</span></div><div><span style="color:rgb(23,43,77);font-family:"DejaVu Sans",sans-serif;font-size:14px"><br></span></div><div><span style="color:rgb(23,43,77);font-family:"DejaVu Sans",sans-serif;font-size:14px"><br></span></div><div><span style="color:rgb(23,43,77);font-family:"DejaVu Sans",sans-serif;font-size:14px">> </span><i><span style="color:rgb(23,43,77);font-family:"DejaVu Sans",sans-serif;font-size:14px">is it reasonable to consider that ServiceLoader is the *only* vector by which the implementation class will be instantiated?<span class="gmail-Apple-converted-space"> </span></span></i></div><div><span style="color:rgb(23,43,77);font-family:"DejaVu Sans",sans-serif;font-size:14px"><br></span></div><div><span style="color:rgb(23,43,77);font-family:"DejaVu Sans",sans-serif;font-size:14px">In my view this is expected and imo I get there by thinking in the opposite direction from the provides p.S type to the requires static rather than the other way around. That is, the p.S type is only available via requires static hence it is expected to potentially not exist at runtime in the module-path. That is, if p.S was expected to exist at runtime it would be "read" via a requires or requires transient clause and not via a requires static - <i>the use of requires static for this case is explicit and intentional</i>.  </span></div><div><span style="color:rgb(23,43,77);font-family:"DejaVu Sans",sans-serif;font-size:14px"><br></span></div><div><span style="color:rgb(23,43,77);font-family:"DejaVu Sans",sans-serif;font-size:14px">In using requires static ... imo we are explicitly going out-of-our-way to say "the types here might not be available at runtime" and the classic case for this as I see it is this case of providing an optional service, that will only be service loaded if the user of that service is in the classpath / module-path. <i>IF</i> the module that is the user of a service is in the classpath / module-path then that module will ensure that the p.S type is in the module-path.</span></div><div><span style="color:rgb(23,43,77);font-family:"DejaVu Sans",sans-serif;font-size:14px"><br></span></div><div><br></div><div><span style="color:rgb(23,43,77);font-family:"DejaVu Sans",sans-serif;font-size:14px">Cheers, Rob.</span></div><div><span style="color:rgb(23,43,77);font-family:"DejaVu Sans",sans-serif;font-size:14px"><br></span></div><div><div><span style="color:rgb(23,43,77);font-family:"DejaVu Sans",sans-serif;font-size:14px">Would a real world example help?</span></div><div><span style="color:rgb(23,43,77);font-family:"DejaVu Sans",sans-serif;font-size:14px"><br></span></div><div><span style="color:rgb(23,43,77);font-family:"DejaVu Sans",sans-serif;font-size:14px">- avaje-inject has a Plugin interface, and will look to load Plugin implementations at runtime.</span></div><div><span style="color:rgb(23,43,77);font-family:"DejaVu Sans",sans-serif;font-size:14px">- avaje-config is a module that has its own functions (external configuration) but can also provide a Plugin for avaje-inject (provide external configuration for dependency injection).</span></div><div><span style="color:rgb(23,43,77);font-family:"DejaVu Sans",sans-serif;font-size:14px">- avaje-jsonb is a module that has its own functions (json marshalling) but can also provide a Plugin for avaje-inject (provide default json marshalling implementation for dependency injection).</span></div><br class="gmail-Apple-interchange-newline"></div><div><span style="color:rgb(23,43,77);font-family:"DejaVu Sans",sans-serif;font-size:14px"><br></span></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, 18 Apr 2023 at 01:23, Alan Bateman <<a href="mailto:Alan.Bateman@oracle.com">Alan.Bateman@oracle.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">

  
  <div>
    On 17/04/2023 14:14, Rob Bygrave wrote:<br>
    <blockquote type="cite">
      
      <div dir="ltr">I'm seeing a runtime error I was not expecting.
        <div><br>
        </div>
        <div><i>Error occurred during initialization of boot layer<br>
            java.lang.module.ResolutionException: Module io.avaje.config
            does not read a module that exports io.avaje.inject.spi</i><br>
        </div>
        <div><br>
        </div>
      </div>
    </blockquote>
    <br>
    JDK-8299504 [1] captures a number of comments on this scenario. <br>
    <br>
    -Alan<br>
    <br>
    [1] <a href="https://bugs.openjdk.org/browse/JDK-8299504" target="_blank">https://bugs.openjdk.org/browse/JDK-8299504</a><br>
  </div>

</blockquote></div>