Registering implementations with ServiceLoader
Some Deephaven Enterprise extension points, such as custom table access,
are discovered at runtime using java.util.ServiceLoader, a standard part of the Java platform. This page is a
short primer on registering a provider for one of these extension points; see the ServiceLoader
Javadoc for the full specification.
The three pieces
- The service — the interface or abstract class defined by the feature you're extending.
- The provider — your implementation of the service. It must be a
publicclass with either apublicno-argument constructor or (since Java 9) apublic static provider()method that returns an instance. - The provider-configuration file — a text file telling
ServiceLoaderwhich of your classes implement which service.
Registering a provider
Create a file at META-INF/services/<binary name of the service>, on the classpath (in a typical Gradle project, that's
src/main/resources/META-INF/services/..., so it ends up in your jar). The file is UTF-8 text, with one fully qualified
provider class name per line; blank lines and lines starting with # are ignored.
Both the file name and its contents use binary names, not source-level names; for a nested type, that means $
rather than .. For example, a provider for Database.TableAccessAdapter.Provider (nested inside Database) is
registered with a file named:
This file contains the fully qualified name of your implementation class, e.g., com.example.MyTableAccessAdapterProvider.
Misconfiguration (for example, a missing or misnamed file, a provider class that can't be instantiated) fails silently at runtime rather than at compile time. Confirm that your provider is discovered rather than assuming it is.
Automating with Google AutoService
Hand-maintaining this file is error-prone: a typo or a forgotten $ for a nested type breaks discovery. Google AutoService
is an annotation processor that generates the file at compile time:
This is a convenience, not a requirement: ServiceLoader has no idea whether a META-INF/services file was hand-written
or generated, so use whatever fits your own build tooling, or just write the file by hand as shown above.