<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 Fri, Dec 13, 2024 at 3:09 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 12/12/2024 14:35, David Lloyd wrote:<br>
    <blockquote type="cite">
      
      <div dir="ltr">
        <div dir="ltr">
          <div style="font-family:arial,helvetica,sans-serif"><span style="font-family:Arial,Helvetica,sans-serif">On Thu, Dec
              12, 2024 at 7:27 AM Alan Bateman <<a href="mailto:alan.bateman@oracle.com" target="_blank">alan.bateman@oracle.com</a>>
              wrote:</span></div>
        </div>
        <div class="gmail_quote">
          <blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
            <div>If ServiceLoader.load is invoked with a ClassLoader
              then it lazily iterates through the class loader
              delegation chain. If ServiceLoader.load is invoked with a
              ModuleLayer then it iterates through the module layers. 
              The former has deliberately limited support for cases
              where a class loader is used by a module layer but doing
              what you propose is adding more complexity for what seems
              like a really niche usage. I would worry that changing it
              along the lines you propose would result in something that
              only a few people could understand.<br>
              <br>
              Have you looked at changing these frameworks to work with
              modules and specify a module layer to ServiceLoader.load?<br>
            </div>
          </blockquote>
          <div><br>
          </div>
          <div style="font-family:arial,helvetica,sans-serif">The problem
            is that 100% of these frameworks are required to work on the
            class path as well (and some are not yet being tested on the
            module path, or even defining an automatic module name,
            though I've been working to improve that for a couple years
            now). So, we'd need some kind of non-trivial fallback logic
            to try both the correct layer (if any) or the correct class
            loader (since the unnamed module has no layer). Also note
            that "correct" depends on the framework: some are using the
            caller, some are using the TCCL, some are using their own
            class loader, some are using a configured class loader, etc.
            It also would likely involve deduplication of returned
            services along with coping with ordering, which is sometimes
            significant. I think it's unlikely that we would be able to
            settle on a preferred pattern for this, and even more
            unlikely that we would be able to successfully push these
            changes to *all* Jakarta, Microprofile, etc. spec APIs in
            addition to non-spec APIs (even the ones that Red Hat
            "controls" would probably give resistance unless the change
            was really clean/simple).</div>
          <br>
        </div>
      </div>
    </blockquote>
    This comes across as a soup of complexity. I can't help thinking it
    would be much simpler to use module layers as originally envisaged,
    meaning each configuration/layer layer is a graph of modules with a
    single parent. Whether the modules are mapped to a single class
    loader or different class loaders should just work. Existing code
    that uses ServiceLoader with a class loader would have a much better
    chance of working in that scenario.</div></blockquote><div><br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">The problem with having one (or a few) broad layer for all named modules is twofold: first, that every module that *might* be needed for an application must be found and loaded before *any* module is able to be loaded. This works in some simpler packaging scenarios but is too startup-heavy in cases with very large numbers of modules. The "--add-modules" switch on the Java launcher is a direct result of forbidding late binding of modules. From a usability perspective, this is already far from ideal, and if you start talking about hundreds or thousands of modules, it becomes completely unworkable. The second problem is that it makes it very difficult to support any kind of dynamicity (for example adding additional plugins/service implementations at run time) since an outsized amount of static analysis must be done to categorize the layers, whereas lazily loading layers solves the problem easily and elegantly.</div></div><div><br></div><span class="gmail_signature_prefix">-- </span><br><div dir="ltr" class="gmail_signature"><div dir="ltr">- DML • he/him<br></div></div></div>