> On 22 Apr 2023, at 02:19, Johannes Spangenberg > <johannes.spangenb...@hotmail.de> wrote: > > Hello, I couldn't quite follow some of the arguments regarding this topic. I > wasn't sure if I should interfere, but I hope it will be helpful now that I > did. :/ > >> But the flip side of that is that if they choose not to use X, Y would just >> sit there, unused. Best case scenario, it would just increase their image >> size; worst-case scenario is that it could preclude some future >> optimisations that may require a full program analysis. > > Not sure about the worst-case. The current implementation already checks > during initialization whether the service is usable. After all, it throws an > exception when it is not. Any optimization can just ignore the service > provider in such case. There is no full program analysis required, which is > not already part of every module initialization.
The module graph analysis doesn’t look inside modules. It cannot exclude the service implementation if it’s *part* of a module, as it doesn’t know whether other parts of the module rely on the classes needed for the service. > > Why do you need ... The runtime doesn’t know why Y `requires static X` or what parts of Y depend on X. This means that code goes back to the classpath’s loosey-goosey attitude and to relying on CNFE, losing one of modules’ goals (reliable configuration). We want to *discourage* `requires static` when used for classes that are relied upon at runtime (as opposed to just compile-time) not encourage it. > > I am not quite sure about the behavior if you stack multiple module layers on > top of each other. I think the service loader should only load instances that > implement the class from the same module layer as the class instance given to > the service loader. Everything else would cause a runtime error independent > of the issue we are currently discussing. In this case, ignoring the provides > clause would be the right solution, even if X would be available on another > module layer. > > I currently see only two reasons for keeping the current behavior. The first > one is to discourage service providers to be casually added to modules. You > could argue that service providers should have their own module, so that > users can add and remove them individually. The second reason might be the > desire to fail early when the service interface was renamed or removed after > updating X. Only the second one, which is another way of saying reliable configuration. > This could be addressed by adding a modifier like `provides static`, there is > no need to correlate the provides cluase with a specific `requires` clause. It can be even better addressed by multi-module JARs, since with “provides static” you'd still have an indeterminate portion of a module not subject to reliable configuration. In addition, it’s simpler and also benefits other use cases. — Ron