This is my controller
package example.infra.adapters.input.api.v1.endpoints
import example.aplication.services.authentication.LoginAuthenticator
import example.aplication.dtos.authentication.CredencialsDTO
import example.aplication.dtos.authentication.AuthenticationTokenDTO
import example.aplication.exceptions.authentication.AuthenticationErrorException
import org.springframework.web.bind.annotation.*
import org.springframework.http.ResponseEntity
import io.swagger.v3.oas.annotations.Operation
import io.swagger.v3.oas.annotations.tags.Tag
import io.swagger.v3.oas.annotations.media.Content
import io.swagger.v3.oas.annotations.media.ExampleObject
import io.swagger.v3.oas.annotations.media.Schema
import io.swagger.v3.oas.annotations.responses.ApiResponse
import io.swagger.v3.oas.annotations.parameters.RequestBody
@RestController
@RequestMapping("/api/v1/authentication")
@Tag(name = "Authentication", description = "User authentication")
class AuthenticationApiController {
LoginAuthenticator loginAuthenticator
@PostMapping(value = "/token")
@Operation(
summary = "Get authentication token",
requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(
required = true,
content = @Content(
mediaType = "application/json",
schema = @Schema(implementation = CredencialsDTO),
examples = [
@ExampleObject(
value = '{"login": "loginExample", "senha": "senhaExample"}'
)
]
)
),
responses = [
@ApiResponse(
responseCode = "200",
description = "Success",
content = @Content(
mediaType = "application/json",
schema = @Schema(implementation = AuthenticationTokenDTO),
examples = [
@ExampleObject(
value = '{"token": "abc123", "expiration": "2025-09-03T18:00:00Z"}'
)
]
)
),
@ApiResponse(
responseCode = "401",
description = "Incorrect login or password",
content = @Content()
)
]
)
ResponseEntity<?> token(@org.springframework.web.bind.annotation.RequestBody CredencialsDTO credencials) {
try {
AuthenticationTokenDTO tokenDto = loginAuthenticator.authenticate(credencials)
return JsonResponse.success(tokenDto)
} catch (AuthenticationErrorException e) {
return JsonResponse.unauthorized()
}
}
}
This is a simple "getToken" endpoint. But when I try to run my app (grails run-app --port 8080) I have this error:
| Running application... Configuring Spring Security Core ... ... finished configuring Spring Security Core 2025-09-04 14:58:23.510 ERROR --- [ restartedMain] o.s.boot.SpringApplication : Application run failedorg.springframework.beans.factory.BeanCreationException: Error creating bean with name 'requestMappingHandlerMapping' defined in org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration: Invocation of init method failed; nested exception is java.lang.IllegalStateException: Ambiguous mapping. Cannot map 'authenticationApiController' method example.infra.adapters.input.api.v1.endpoints.AuthenticationApiController#token(CredencialsDTO) to {POST [/api/v1/authentication/token]}: There is already 'authenticationApiController' bean method example.infra.adapters.input.api.v1.endpoints.AuthenticationApiController#token() mapped. at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1804) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:620) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:955) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:147) at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:731) at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:408) at org.springframework.boot.SpringApplication.run(SpringApplication.java:307) at grails.boot.GrailsApp.run(GrailsApp.groovy:99) at grails.boot.GrailsApp.run(GrailsApp.groovy:485) at grails.boot.GrailsApp.run(GrailsApp.groovy:472) at grails.boot.GrailsApp$run.call(Unknown Source) at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:148) at agriwin.Application.main(Application.groovy:15) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) Caused by: java.lang.IllegalStateException: Ambiguous mapping. Cannot map 'authenticationApiController' method example.infra.adapters.input.api.v1.endpoints.AuthenticationApiController#token(CredencialsDTO) to {POST [/api/v1/authentication/token]}: There is already 'authenticationApiController' bean method example.infra.adapters.input.api.v1.endpoints.AuthenticationApiController#token() mapped. at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping$MappingRegistry.validateMethodMapping(AbstractHandlerMethodMapping.java:669) at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping$MappingRegistry.register(AbstractHandlerMethodMapping.java:635) at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.registerHandlerMethod(AbstractHandlerMethodMapping.java:332) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping.registerHandlerMethod(RequestMappingHandlerMapping.java:420) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping.registerHandlerMethod(RequestMappingHandlerMapping.java:76) at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.lambda$detectHandlerMethods$2(AbstractHandlerMethodMapping.java:299) at java.util.LinkedHashMap.forEach(LinkedHashMap.java:684) at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.detectHandlerMethods(AbstractHandlerMethodMapping.java:297) at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.processCandidateBean(AbstractHandlerMethodMapping.java:266) at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.initHandlerMethods(AbstractHandlerMethodMapping.java:225) at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.afterPropertiesSet(AbstractHandlerMethodMapping.java:213) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping.afterPropertiesSet(RequestMappingHandlerMapping.java:205) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1863) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1800) ... 26 common frames omitted
Some considerations:
- I don't have another "token" method in any controller of my project.
- Im using java 8 + springboot 2.7.8 + grails 5.3
- My dependencies about spring doc api: 'org.springdoc:springdoc-openapi-ui:1.8.0' and 'org.springdoc:springdoc-openapi-groovy:1.8.0'.
- If I remove "Controller" from my file name and remove from my class declaration, like: AuthenticationApi.groovy -> Class AuthenticationApi {} it works, my project runs normally and my swagger works fine.
- I've tryied to change my method name and no work, had the same problem.
- I see some java examples, and they have a ExampleController.java with anotation @RestController, just it.
- I had see some guys with this problem but they really have 2 methods mapped in a same endPoint and the solution is use @PostMapping(value = "...") to the different endPoints.
- I can't find any groovy/grails project example with spring doc api swagger.
Any sugestions?
autenticacaorelate to this problem? Is there another controller doing the same? Is there some residue from testing still around in the build directory (e.g. does cleaning the project help)?tokenmethod without an argument? The giventokenmethod not having a default argument for theCredentialsDTO?