Problem
java.util.ServiceLoader (Java 9+) supports two provider shapes: a public no‑arg constructor, or a public static provider() factory method returning the service type. The processor implicitly assumes the constructor form and offers no way to register a provider that exposes a static provider() method, even though such a class is a valid SPI provider.
Evidence
- Generation writes the provider's binary name into
META-INF/services/<contract> (ServiceSchemeProcessor.kt:156-170) with no awareness of provider methods.
- Discovery is purely annotation‑driven on the class (
ServiceSchemeProcessor.kt:48-63); there is no recognition of a static provider() factory.
- README only shows the constructor form (
README.md:71-92).
Proposed implementation
- Detect a public
static <ContractType> provider() method on annotated providers and treat it as a valid registration (the service‑file entry stays the provider class name; ServiceLoader handles the factory automatically).
- Combine with provider‑instantiability validation (separate issue): a provider is valid if it has either a public no‑arg constructor or a public static
provider() method.
- Document the factory‑method option in the README.
Acceptance criteria
- A provider exposing only a public static
provider() method is accepted and loadable at runtime via ServiceLoader.
- Tests cover the provider‑method form (Java + Kotlin
@JvmStatic).
Problem
java.util.ServiceLoader(Java 9+) supports two provider shapes: a public no‑arg constructor, or a public staticprovider()factory method returning the service type. The processor implicitly assumes the constructor form and offers no way to register a provider that exposes a staticprovider()method, even though such a class is a valid SPI provider.Evidence
META-INF/services/<contract>(ServiceSchemeProcessor.kt:156-170) with no awareness of provider methods.ServiceSchemeProcessor.kt:48-63); there is no recognition of astatic provider()factory.README.md:71-92).Proposed implementation
static <ContractType> provider()method on annotated providers and treat it as a valid registration (the service‑file entry stays the provider class name; ServiceLoader handles the factory automatically).provider()method.Acceptance criteria
provider()method is accepted and loadable at runtime viaServiceLoader.@JvmStatic).