Skip to content

feat(processor): validate that providers are instantiable by ServiceLoader #41

Description

@LMLiam

Problem

The processor does not verify that a @ServiceProvider class is actually instantiable by ServiceLoader. ServiceLoader requires a provider to be a public, concrete class with a public no‑arg constructor (or a public static provider() method). Annotating an abstract class, a non‑public class, a Kotlin object/inner class, or a class with only parameterized constructors compiles fine but fails at runtime with ServiceConfigurationError. These are exactly the mistakes the tool exists to prevent.

Evidence

  • addProvider records providers with no instantiability checks (ServiceSchemeProcessor.kt:172-181).
  • validateProviderTargets only checks the target is a @ServiceContract (ServiceSchemeProcessor.kt:133-154).
  • @ServiceProvider targets classes (modules/annotations/.../ServiceScheme.kt:10,12-14), so it can be placed on abstract/non‑instantiable classes.
  • The runtime integration test only exercises a well‑formed provider (ServiceSchemeProcessorSpec.kt:801-859), so these failure modes are uncaught.

Proposed implementation

At registration time, emit Diagnostic.Kind.ERROR (tied to the element) when the provider is not loadable by ServiceLoader:

  • not public (top‑level/static nested), or abstract, or a non‑static inner class, and
  • lacks both a public no‑arg constructor and a public static provider() method (coordinate with the provider‑method feature issue).
    For Kotlin, account for object (no public ctor) and visibility mapping.

Acceptance criteria

  • Annotating a non‑instantiable class with @ServiceProvider fails compilation with an actionable message.
  • Valid providers still pass; tests cover abstract class, non‑public class, missing no‑arg ctor, and (if applicable) Kotlin object.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:processorAnnotation processor: discovery, validation, META-INF/services generationstatus:readyTriaged and ready for worktype:featureFeature request or enhancement

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions