Skip to content

Conflict between HealthEndpointConfiguration and AvailabilityProbesAutoConfiguration #44052

Open
@edudar-chwy

Description

Environment:

  • Spring Boot: 3.4.2
  • Spring: 6.2.2
  • Kubernetes

After upgrading to Spring Boot 3.4 from 3.3 I see an unexpected ClassCastException while calling /health endpoints on Kubernetes, specifically because this works locally as availability probes are not enabled unless in Kubernetes or CloudFoundry or explicitly in properties:

class org.springframework.boot.actuate.autoconfigure.availability.AvailabilityProbesHealthEndpointGroups cannot be cast to class org.springframework.boot.actuate.endpoint.web.AdditionalPathsMapper

While tracing it down, I narrowed the change to #40962 and this commit when additionalPathsMappers were added to WebEndpointDiscoverer.

HealthEndpointConfiguration creates a bean of type HealthEndpointGroups named healthEndpointGroups with the instance of AutoConfiguredHealthEndpointGroups that implements HealthEndpointGroups, AdditionalPathsMapper.

At the same time, AvailabilityProbesAutoConfiguration creates a post-processor of type AvailabilityProbesHealthEndpointGroupsPostProcessor that, in turn, also creates a bean of HealthEndpointGroups but using an instance of AvailabilityProbesHealthEndpointGroups that implements only HealthEndpointGroups but not AdditionalPathsMapper.

When WebEndpointAutoConfiguration creates webEndpointDiscoverer it autowires ObjectProvider<AdditionalPathsMapper> additionalPathsMappers and uses additionalPathsMappers.orderedStream().toList() but this calls hides the problem due to generics. Calling additionalPathsMappers.getIfAvailable() fails with BeansNotOfRequiredTypeException which is correct.

Digging deeper into additionalPathsMappers.orderedStream(), I see DefaultListableBeanFactory.findAutowireCandidates() tries to find candidateNames by AdditionalPathsMapper.class and gets "healthEndpointGroups", but when beanfactory gets a bean by that name, it is AvailabilityProbesHealthEndpointGroups which does not implement AdditionalPathsMapper. Because of generics, this issue is not showing up all the way until DiscoveredWebEndpoint.getAdditionalPaths() is called because if explicitly requires AdditionalPathsMapper but gets AvailabilityProbesHealthEndpointGroups which is not.

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions