Uploaded image for project: 'Spring Integration'
  1. Spring Integration
  2. INT-4201

GatewayMethodInboundMessageMapper - annotation alias resolution not working

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Minor
    • Resolution: Complete
    • Affects Version/s: 4.3.5
    • Fix Version/s: 5.0.M2, 4.3.7
    • Component/s: Core
    • Labels:

      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.

        Attachments

          Activity

            People

            Assignee:
            grussell Gary Russell
            Reporter:
            hattifnat Adam Michalik
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Dates

              Created:
              Updated:
              Resolved: