Search code examples
kotlinmicronaut

Resolving a «multiple possible bean candidates» conflict in Micronaut


I got this error while trying to create a custom OpenIdAuthenticationMapper. This code will make a request to an Oauth server to get the identification code and token. I don't know how to convert the AuthenticationResponse.success to Publisher<AuthenticationResponse>.

Micronaut: 4.2.1

ERROR io.micronaut.runtime.Micronaut - Error starting Micronaut server: Failed to inject value for parameter [authenticationMapper] of class: io.micronaut.security.oauth2.endpoint.authorization.response.DefaultOpenIdAuthorizationResponseHandler

Message: Multiple possible bean candidates found: [DefaultOpenIdAuthenticationMapper, MyOpenIdAuthenticationMapper]

@Singleton
@Named("my")
class MyOpenIdAuthenticationMapper(
    ...
) : OpenIdAuthenticationMapper {
    @NonNull
    override fun createAuthenticationResponse(
        providerName: String,
        tokenResponse: OpenIdTokenResponse,
        openIdClaims: OpenIdClaims,
        @Nullable state: State?
    ): Publisher<AuthenticationResponse> {
       # Make request to Oauth server
        ...

        val attributes = mapOf(
            ...
        )

        return Mono.create { AuthenticationResponse.success(identificationCode, emptyList(), attributes) }
    }
}

Solution

  • Micronaut finds two bean candidates of type OpenIdAuthenticationMapper in your application context and therefore it fails, because it does not know how to resolve that conflict.

    To resolve this conflict you've got to help Micronaut using the following options:

    Mark your bean as the primary

    Use @Primary to tell Micronaut to choose your bean, to resolve the multiple possible bean candidates conflict.

    @Singleton
    @Primary
    class MyOpenIdAuthenticationMapper : OpenIdAuthenticationMapper {}
    

    Replace the DefaultOpenIdAuthenticationMapper

    You can replace the DefaultOpenIdAuthenticationMapper with your implementation by adding @Replace

    @Singleton
    @Replaces(DefaultOpenIdAuthenticationMapper)
    class MyOpenIdAuthenticationMapper : OpenIdAuthenticationMapper {}
    

    to your class. This will make sure there is only one OpenIdAuthenticationMapper bean in the application context.

    Further readings