Search code examples
spring-bootrabbitmqspring-cloudspring-cloud-streamspring-rabbit

No converter found capable of converting from type [byte[]] to type [CustomClass]


I was using spring-boot 1.5.9.RELEASE and spring cloud version Edgware.SR1 to send messages from one app to RabbitMQ and later retrieving the message in this way:

Send message:

public interface EventNotificationChannel {
    @Output
    MessageChannel moneyTransferredChannel();
}


@Slf4j
@RestController
public class TransferController {

    private final MessageChannel channel;

    public TransferController(EventNotificationChannel channel) {
        channel = channel.myChannel();
    }

    @PostMapping("/mapping")
    public void do(@RequestBody CustomClass customClass) {
        Message<CustomClass> event =
                 MessageBuilder.withPayload(customClass).build();
        this.channel.send(event);
    }
}

Retrieve message:

@Bean
IntegrationFlow integrationFlow(EventNotificationChannel channel) {
        return IntegrationFlows.from(channel.subscriptionOnMyChannel()).
                handle(CustomClass, (payload, headers) -> {
// do something with the payload - payload instanceOf CustomClass
                    return null;
                }).get();
    }

After upgrading my version to

spring-boot 2.0.0.RELEASE
spring-cloud-version Finchley.M9

I'm retrieving this exception:

org.springframework.amqp.rabbit.listener.exception.ListenerExecutionFailedException: Listener threw exception
    at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.wrapToListenerExecutionFailedExceptionIfNeeded(AbstractMessageListenerContainer.java:1506) ~[spring-rabbit-2.0.2.RELEASE.jar:2.0.2.RELEASE]
    at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:1417) ~[spring-rabbit-2.0.2.RELEASE.jar:2.0.2.RELEASE]
    at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.actualInvokeListener(AbstractMessageListenerContainer.java:1337) ~[spring-rabbit-2.0.2.RELEASE.jar:2.0.2.RELEASE]
    at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:1324) ~[spring-rabbit-2.0.2.RELEASE.jar:2.0.2.RELEASE]
    at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:1303) ~[spring-rabbit-2.0.2.RELEASE.jar:2.0.2.RELEASE]
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doReceiveAndExecute(SimpleMessageListenerContainer.java:785) [spring-rabbit-2.0.2.RELEASE.jar:2.0.2.RELEASE]
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.receiveAndExecute(SimpleMessageListenerContainer.java:769) [spring-rabbit-2.0.2.RELEASE.jar:2.0.2.RELEASE]
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$700(SimpleMessageListenerContainer.java:77) [spring-rabbit-2.0.2.RELEASE.jar:2.0.2.RELEASE]
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1010) [spring-rabbit-2.0.2.RELEASE.jar:2.0.2.RELEASE]
    at java.lang.Thread.run(Thread.java:745) [na:1.8.0_66]
Caused by: org.springframework.messaging.MessageHandlingException: error occurred in message handler [ServiceActivator for [org.springframework.integration.handler.LambdaMessageProcessor@af60a61] (org.springframework.integration.handler.ServiceActivatingHandler#0)]; nested exception is org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [byte[]] to type [com.CustomClass]

It looks I have to register my own converter or so since (my guess) the relevant part of the stack trace is:

nested exception is org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [byte[]] to type [com.CustomClass]

Is there a way to make this code work again? Thanks for your help


Solution

  • This is so weird but it looks like the issue is related with the lambda support, this code works in this case:

    @Bean
    IntegrationFlow integrationFlow(EventNotificationChannel channel) {
            return IntegrationFlows.from(channel.subscriptionOnMyChannel()).
                    handle(CustomClass, new GenericHandler<CustomClass>() {
                    @Override
                    public Object handle(CustomClass payload, 
                                        Map<String, Object> headers) {
                    // do something with the payload
                        return null;
                    }}).get();
        }