Java's ServiceLoader
class is now officially baked into the Java language. Instead of looking for providers in META-INF/services
you can now use the
provides <spiClass> with <providerClass>
What I fail to understand is, the use of uses
in the service loading module declaration:
uses <spiClass>
Quoting from The State of the Module System
The module system could identify uses of services by scanning the class files in module artifacts for invocations of the
ServiceLoader::load
methods, but that would be both slow and unreliable. That a module uses a particular service is a fundamental aspect of that module’s definition, so for both efficiency and clarity we express that in the module’s declaration with a uses clause:module java.sql { requires transitive java.logging; requires transitive java.xml; exports java.sql; exports javax.sql; exports javax.transaction.xa; uses java.sql.Driver; }
Why is it fundamental for the module system to know uses of a particular service, especially how will this introduce efficiency? Aren't services loaded lazily? Why can't the service loader just look for providers on the fly?
The main goals for Java 9 are to: Make the Java Standard Edition platform, and the JDK, more navigable to scale down for small computing devices. Improve the overall security and maintain not only the JDK but the Java Implementations in general. Allow overall improved application performance.
module-info. java file. It declares the dependencies within the module system and allows the compiler and the runtime to police the boundaries/access violations between the modules in your application. Let's look at the file syntax and the keywords you can use.
Defining the Java 9 module. A module is a collection of code, data, and resources. It is a set of related packages and types (classes, abstract classes, interfaces, and more) with code, data files, and some static resources.
A 'requires' directive (irrespective of 'transitive') expresses that one module depends on some other module. The effect of the 'transitive' modifier is to cause additional modules to also depend on the other module.
When the JVM launches, the module system resolves dependencies and builds the module graph. Only modules that make it into the graph are available at run time (even if others are observable). If modules are properly decoupled via services, there is a good chance, though, that the providing modules are not transitive dependencies of the initial module. So without further efforts, service provider modules would routinely not make it into the module graph and thus not be available at run time when a module tries to use a service.
In order for the
java.sql
module to make use of this driver [...] the module system must add the driver module to the module graph and resolve its dependencies [...].
So for services to properly work, provider modules must make it into the module graph even if they are not transitively required from the initial module. But how can the module system identify which modules are needed as service providers? All that use a provides
clause? That would be a little too much. No, only providers of services that are actually needed should be resolved.
This makes it necessary to identify services uses. As others have pointed out, bytecode analysis is slow and unreliable, so a more explicit mechanism is needed to guarantee efficiency and correctness: uses
clauses. Only with them can the module system reliably and efficiently make all service provider modules available.
If the application is a module, then its module declaration must have a
uses
directive that specifies the service; this helps to locate providers and ensure they will execute reliably.
You can observe this behavior if launching a service-based application with the flag --show-module-resolution
:
root monitor
monitor requires monitor.observer
[...]
monitor binds monitor.observer.beta
monitor binds monitor.observer.alpha
The module monitor binds the modules monitor.observer.alpha
and monitor.observer.beta
even though it does not depend on either of them.
(Quotes are from The State of the Module System; emphasis mine.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With