Spring boot version 3.3.0 Java version - 21
Sample code -
@Component
@Endpoint(id = "customEndpoint")
public class CustomEndpoint {
@WriteOperation
public Mono<String> performCustomOperation(@Selector String parameter1, @Selector int parameter2) {
return Mono.just("Custom operation performed with parameters: " + parameter1 + ", " + parameter2);
}
}
Error -
Caused by: java.lang.IllegalStateException: Failed to extract parameter names for public reactor.core.publisher.Mono com.atext.messaging.common.service.CustomEndpoint.performCustomOperation(java.lang.String,int)
at org.springframework.util.Assert.state(Assert.java:97) ~[spring-core-6.1.8.jar:6.1.8]
at org.springframework.boot.actuate.endpoint.invoke.reflect.OperationMethodParameters.<init>(OperationMethodParameters.java:51) ~[spring-boot-actuator-3.3.0.jar:3.3.0]
at org.springframework.boot.actuate.endpoint.invoke.reflect.OperationMethod.<init>(OperationMethod.java:55) ~[spring-boot-actuator-3.3.0.jar:3.3.0]
at org.springframework.boot.actuate.endpoint.annotation.DiscoveredOperationMethod.<init>(DiscoveredOperationMethod.java:43) ~[spring-boot-actuator-3.3.0.jar:3.3.0]
at org.springframework.boot.actuate.endpoint.annotation.DiscoveredOperationsFactory.createOperation(DiscoveredOperationsFactory.java:93) ~[spring-boot-actuator-3.3.0.jar:3.3.0]
at org.springframework.boot.actuate.endpoint.annotation.DiscoveredOperationsFactory.lambda$createOperation$1(DiscoveredOperationsFactory.java:80) ~[spring-boot-actuator-3.3.0.jar:3.3.0]
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197) ~[na:na]
at java.base/java.util.Collections$UnmodifiableMap$UnmodifiableEntrySet.lambda$entryConsumer$0(Collections.java:1778) ~[na:na]
at java.base/java.util.Spliterators$IteratorSpliterator.tryAdvance(Spliterators.java:1950) ~[na:na]
at java.base/java.util.Collections$UnmodifiableMap$UnmodifiableEntrySet$UnmodifiableEntrySetSpliterator.tryAdvance(Collections.java:1797) ~[na:na]
at java.base/java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:129) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:527) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:513) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499) ~[na:na]
at java.base/java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:150) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[na:na]
at java.base/java.util.stream.ReferencePipeline.findFirst(ReferencePipeline.java:647) ~[na:na]
at org.springframework.boot.actuate.endpoint.annotation.DiscoveredOperationsFactory.createOperation(DiscoveredOperationsFactory.java:82) ~[spring-boot-actuator-3.3.0.jar:3.3.0]
at org.springframework.boot.actuate.endpoint.annotation.DiscoveredOperationsFactory.lambda$createOperations$0(DiscoveredOperationsFactory.java:73) ~[spring-boot-actuator-3.3.0.jar:3.3.0]
at org.springframework.core.MethodIntrospector.lambda$selectMethods$0(MethodIntrospector.java:75) ~[spring-core-6.1.8.jar:6.1.8]
at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:366) ~[spring-core-6.1.8.jar:6.1.8]
at org.springframework.core.MethodIntrospector.selectMethods(MethodIntrospector.java:73) ~[spring-core-6.1.8.jar:6.1.8]
at org.springframework.boot.actuate.endpoint.annotation.DiscoveredOperationsFactory.createOperations(DiscoveredOperationsFactory.java:73) ~[spring-boot-actuator-3.3.0.jar:3.3.0]
at org.springframework.boot.actuate.endpoint.annotation.EndpointDiscoverer.addOperations(EndpointDiscoverer.java:211) ~[spring-boot-actuator-3.3.0.jar:3.3.0]
at org.springframework.boot.actuate.endpoint.annotation.EndpointDiscoverer.convertToEndpoint(EndpointDiscoverer.java:191) ~[spring-boot-actuator-3.3.0.jar:3.3.0]
at org.springframework.boot.actuate.endpoint.annotation.EndpointDiscoverer.convertToEndpoints(EndpointDiscoverer.java:182) ~[spring-boot-actuator-3.3.0.jar:3.3.0]
at org.springframework.boot.actuate.endpoint.annotation.EndpointDiscoverer.discoverEndpoints(EndpointDiscoverer.java:125) ~[spring-boot-actuator-3.3.0.jar:3.3.0]
at org.springframework.boot.actuate.endpoint.annotation.EndpointDiscoverer.getEndpoints(EndpointDiscoverer.java:117) ~[spring-boot-actuator-3.3.0.jar:3.3.0]
at org.springframework.boot.actuate.autoconfigure.health.HealthEndpointReactiveWebExtensionConfiguration$WebFluxAdditionalHealthEndpointPathsConfiguration.healthEndpointWebFluxHandlerMapping(HealthEndpointReactiveWebExtensionConfiguration.java:69) ~[spring-boot-actuator-autoconfigure-3.3.0.jar:3.3.0]
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[na:na]
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:140) ~[spring-beans-6.1.8.jar:6.1.8]
... 35 common frames omitted
Comment From: bclozel
Are you compiling this code with the "-parameters" compiler option? See https://github.com/spring-projects/spring-framework/wiki/Upgrading-to-Spring-Framework-6.x#parameter-name-retention
Comment From: bhrt-DS
Thank you @bclozel , it worked with "-parameters" compiler option. Is this permanent solution?
Comment From: wilkinsona
Yes, that's the permanent and documented solution:
To let the input be mapped to the operation method’s parameters, Java code that implements an endpoint should be compiled with
-parameters
, and Kotlin code that implements an endpoint should be compiled with-java-parameters
. This will happen automatically if you use Spring Boot’s Gradle plugin or if you use Maven and spring-boot-starter-parent.