Spring version: 5.3.6 JDK: 16.0.1

It seems that spring-context-indexer library doesn't support Java records. If I declare a record as Spring bean:

@Component
public record ServiceManager() {}

then META-INF/spring.components doesn't contain entry for this type. And Spring fails to load it during startup. I looked into source code and the following blocks seem to responsible for that:

CandidateComponentsIndexer:

private static final Set<ElementKind> TYPE_KINDS =
 Collections.unmodifiableSet(EnumSet.of(ElementKind.CLASS, ElementKind.INTERFACE));

IndexedStereotypesProvider:

    @Override
    public Set<String> getStereotypes(Element element) {
        Set<String> stereotypes = new LinkedHashSet<>();
        ElementKind kind = element.getKind();
        if (kind != ElementKind.CLASS && kind != ElementKind.INTERFACE) {
            return stereotypes;
        }

Comment From: jhoeller

I wonder why you would want to declare a record as a Spring-managed bean to begin with? Our notion of a "managed bean" seems strongly bound to traditional object semantics, including instance identity and access to delegates. Are records ever a good fit there?

Now, if you're arguing that this is a mismatch between the indexer and runtime component scanning, we should indeed align the behavior there. Even if not a recommended choice of component type, consistently detecting annotated record classes is certainly better than inconsistent runtime behavior.

Comment From: jhoeller

I've locally refined those checks to (element.getKind().isClass() || element.getKind() == ElementKind.INTERFACE) which seems generally sensible and implicitly includes records as well as enum types (even if the latter are not a typical managed bean choice either).

Comment From: sergey-morenets

@jhoeller Thank you for the quick response.

I guess Java records is rather new feature (which was declared stable only in JDK 16) so there' no so much best practices around it. What surprised me is that I can register Java record as Spring bean without spring-context-indexer but unable to register if I turn on spring-context-indexer.

Comment From: sergey-morenets

So I will understand if you remove Java records support at all. But it looks like inconsistent behavior now.