Details
-
Bug
-
Status: Closed
-
Minor
-
Resolution: Complete
-
4.3.5
Description
org.springframework.messaging.handler.annotation.Header has aliasing set between name and value using AliasFor.
However, in my gateway
@MessagingGateway public interface MyGateway { void run(@Header(name = "my_header") String myHeader, @Payload String s); }
when I specify the header name using the name attribute, I get an error:
java.lang.IllegalArgumentException: Cannot determine header name. Possible reasons: -debug is disabled or header name is not explicitly provided via @Header annotation. at org.springframework.util.Assert.notNull(Assert.java:115) at org.springframework.integration.gateway.GatewayMethodInboundMessageMapper.determineHeaderName(GatewayMethodInboundMessageMapper.java:230) at org.springframework.integration.gateway.GatewayMethodInboundMessageMapper.access$500(GatewayMethodInboundMessageMapper.java:81) at org.springframework.integration.gateway.GatewayMethodInboundMessageMapper$DefaultMethodArgsMessageMapper.toMessage(GatewayMethodInboundMessageMapper.java:301) at org.springframework.integration.gateway.GatewayMethodInboundMessageMapper$DefaultMethodArgsMessageMapper.toMessage(GatewayMethodInboundMessageMapper.java:263) at org.springframework.integration.gateway.GatewayMethodInboundMessageMapper.mapArgumentsToMessage(GatewayMethodInboundMessageMapper.java:164) at org.springframework.integration.gateway.GatewayMethodInboundMessageMapper.toMessage(GatewayMethodInboundMessageMapper.java:159) at org.springframework.integration.gateway.GatewayMethodInboundMessageMapper.toMessage(GatewayMethodInboundMessageMapper.java:81) at org.springframework.integration.support.converter.SimpleMessageConverter.toMessage(SimpleMessageConverter.java:106) at org.springframework.messaging.core.AbstractMessageSendingTemplate.doConvert(AbstractMessageSendingTemplate.java:172) at org.springframework.messaging.core.AbstractMessageSendingTemplate.convertAndSend(AbstractMessageSendingTemplate.java:142) at org.springframework.messaging.core.AbstractMessageSendingTemplate.convertAndSend(AbstractMessageSendingTemplate.java:135) at org.springframework.integration.gateway.MessagingGatewaySupport.send(MessagingGatewaySupport.java:375) at org.springframework.integration.gateway.GatewayProxyFactoryBean.invokeGatewayMethod(GatewayProxyFactoryBean.java:477) at org.springframework.integration.gateway.GatewayProxyFactoryBean.doInvoke(GatewayProxyFactoryBean.java:429) at org.springframework.integration.gateway.GatewayProxyFactoryBean.invoke(GatewayProxyFactoryBean.java:420) at org.springframework.integration.gateway.GatewayCompletableFutureProxyFactoryBean.invoke(GatewayCompletableFutureProxyFactoryBean.java:65) ...
When I specify it using the value attribute, it works fine.
I believe it is because:
- GatewayMethodInboundMessageMapper.determineHeaderName() is using
String valueAttribute = (String) AnnotationUtils.getValue(headerAnnotation);
- But for the aliasing to work properly, the annotation has to be previously proxied using one of the AnnotationUtils.find/getAnnotation... methods as described in the AnnotationUtils Javadoc.
- However, the annotations come from the parameters stored in GatewayMethodInboundMessageMapper#parameterList and that is initialized in GatewayMethodInboundMessageMapper#getMethodParameterList with MethodParameter instances which simply delegate to the java.lang.reflect.Method#getParameterAnnotations. So the annotations are not proxied and the aliasing will not work automatically when AnnotationUtils is used.
However, the Javadoc of org.springframework.core.MethodParameter says that
As of 4.2, there is a org.springframework.core.annotation.SynthesizingMethodParameter subclass available which synthesizes annotations with attribute aliases.
If my reasoning is correct, using the SynthesizingMethodParameter instead of MethodParameter in GatewayMethodInboundMessageMapper#getMethodParameterList should be enough to fix it.