<div dir="ltr"><div dir="ltr"><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br></div></div><br><div class="gmail_quote gmail_quote_container"><div dir="ltr" class="gmail_attr">On Sun, Dec 15, 2024 at 1:22 AM 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:1px solid rgb(204,204,204);padding-left:1ex"><u></u>

  
  <div>
    On 13/12/2024 23:57, David Lloyd wrote:<br>
    <blockquote type="cite">
      
      <div dir="ltr">:<br>
        <div class="gmail_quote">
          <div style="font-family:arial,helvetica,sans-serif"><br>
          </div>
          <div style="font-family:arial,helvetica,sans-serif">Another
            behavioral quirk is that service loaders don't actually work
            the same if the service was found in a named module. If a
            service provider class was found in a named module, then the
            loader will also look for a `provider` static method which
            can return the service instance, whereas services found via
            the classic mechanism will only invoke the constructor of
            the service class to acquire its instance. Additionally, the
            classic `META-INF/services` mechanism is still used in
            module mode, however the service provider classes are
            filtered out if they are found to be located in a named
            module after loading the class. Since behavior differs
            between module and non-module mode, a library author which
            seeks to run in both environments while using ServiceLoader
            has to carefully consider how services might be loaded in a
            given environment.</div>
        </div>
      </div>
    </blockquote>
    <br>
    I have some sympathy to the complaint that service providers
    deployed as a module can define a static provider method or public
    constructor whereas service providers deployed on the class path
    must define a public constructor.  The resolution of issue
    #ServiceLoaderEnhancements [1] in JSR 376 did not propose to change
    existing behavior. Maybe that specific ask could be looked at again
    but it would require great care.<br></div></blockquote><div><br></div><div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">Sure, I think that is worth pursuing separately. It is very rare that a library can or will take advantage of this mechanism today because the class path and plain class loading is still very widely used today, and as I said, library authors are generally not keen to exclude any part of their possible audience.</div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div>On "the classic META-INF/services mechanism is still used in module
    mode". I think you mean that creating ServiceLoader with a class
    loader may locate META-INF/services configuration file in a named
    module.</div></blockquote><div><br></div><div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">From tracing through the JDK code, I believe the filtering was happening after each listed class was loaded, so that (for example) if one class was found in a named module, and one was in an unnamed module, only the class found in a named module would be filtered out, but yes, that is the mechanism I'm referring to (though mainly just for completeness).</div></div></div><span class="gmail_signature_prefix">-- </span><br><div dir="ltr" class="gmail_signature"><div dir="ltr">- DML • he/him<br></div></div></div>