The ServiceLoader.java docs notes:
It is strongly recommended that the application module does not require modules which contain providers of the service.
Why is this strongly recommended, what could happen if the recommendation isn't followed?
Context: This indirectly means that modules defining a service shouldn't also export a provider of that service. I thought it would be handy to provide a default implementation of the service within the same module.
Why Not Require Provider Module?
The reason is because the
uses
/provivdes
directives and thejava.util.ServiceLoader
API is designed for a plugin-like architecture. You control which plugins are available by controlling which providers are on the module-path/class-path. If yourequires
the provider module, then you can no longer omit it because the application would fail to launch due to missing dependencies.The Documentation
The documentation you quote makes more sense if you look at the previous sentence as well, which provides more context.
This is addressing the specific case demonstrated below.
Application Module
Service Module
Provider Module
The above is the recommended approach. And what the documentation is saying is that the
app
module should not include arequires provider
directive. The reason why has already been explained.Also, note this does not prevent either the
service
module or theapp
module from providing a default implementation of the service interface.Example Module Resolution
If you create and compile an implementation for the above modules, then you can see the module resolution at run-time via
--show-module-resolution
. I use--limit-modules
below to control which modules are resolved to avoid having to mess around with the module-path. As you can see, sinceapp
does notrequires provider
, it is possible to omitprovider
and still have a working application.My service interface has a
getMessage()
method that simply returns aString
. My main class iterates the available providers, if any, and outputs the provider's class name and "message". This output comes after, and is clearly distinct from, the module resolution output below.Note I load the providers from a static method in the
Service
interface, because theservice
module is where I have theuses
directive for said interface.With Provider Module
Command:
Output:
Without Provider Module
Command:
Output:
Previous Answer
The previous edition of this answer had the following example to demonstrate what the documentation was saying:
Service Module
Provider Module
Not only was I incorrect regarding the purpose of the documentation, but the above is not even possible as the Java Platform Module System does not allow cyclic dependencies at compile-time.