Azure / azure-sdk-for-java

This repository is for active development of the Azure SDK for Java. For consumers of the SDK we recommend visiting our public developer docs at https://docs.microsoft.com/java/azure/ or our versioned developer docs at https://azure.github.io/azure-sdk-for-java.
MIT License
2.35k stars 1.99k forks source link

[BUG] No type field available #24742

Closed khauser closed 3 years ago

khauser commented 3 years ago

Hi,

we have problem upgrading our current message receiver using the methods which worked before.

Message sender uses: compile 'com.azure:azure-messaging-servicebus:7.1.0'

Message receiver uses: implementation group: 'com.azure.spring', name: 'azure-spring-boot-starter-servicebus-jms', version: "3.9.0"

We upgraded from compile group: 'com.microsoft.azure', name: 'azure-servicebus-jms-spring-boot-starter', version: "2.3.5"

The receiver now complains about a missing {{type}} field.

org.springframework.jms.support.converter.MessageConversionException: Could not find type id property [_type] on message [ID:AMQP_NO_PREFIX:44442f21de2a4d5dbe3f92bd7afa96af] from destination [TP_request_queue]
    at org.springframework.jms.support.converter.MappingJackson2MessageConverter.getJavaTypeForMessage(MappingJackson2MessageConverter.java:456)
    at org.springframework.jms.support.converter.MappingJackson2MessageConverter.fromMessage(MappingJackson2MessageConverter.java:232)
    at org.springframework.jms.core.JmsTemplate.doConvertFromMessage(JmsTemplate.java:859)
    at org.springframework.jms.core.JmsTemplate.receiveAndConvert(JmsTemplate.java:829)
    at com.intershop.iste.message.service.azure.AzureBusService.receive(AzureBusService.java:34)
    at com.intershop.iste.message.service.azure.AzureBusMessageReceiver.receiveMessage(AzureBusMessageReceiver.java:25)
    at com.intershop.iste.message.service.MessageService.getMessage(MessageService.java:35)
    at com.intershop.iste.message.controller.AsyncMessageController.getNextMessage(AsyncMessageController.java:69)
    at com.intershop.iste.message.controller.AsyncMessageController.lambda$getMessage$1(AsyncMessageController.java:51)
    at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run(Unknown Source)
    at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
    at datadog.trace.bootstrap.instrumentation.java.concurrent.Wrapper.run(Wrapper.java:25)
    at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
    at java.base/java.util.concurrent.FutureTask.run(Unknown Source)
    at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.base/java.lang.Thread.run(Unknown Source)

Do we miss something?

Best Karsten

joshfree commented 3 years ago

@stliu could you please help route @khauser's issue migrating from Track1 to the new Track 2 azure-servicebus-jms-spring-boot-starter

yiliuTo commented 3 years ago

Hi @khauser thanks for reporting this, could you provide a tiny sample project reproducing this bug, which includes how you send messages to Azure Service Bus and the way you use azure-servicebus-jms-spring-boot-starter to receive and convert messags from SB?

khauser commented 3 years ago

demo-sender.zip demo-receiver.zip

If I remove this file it works:

import org.springframework.boot.autoconfigure.jms.DefaultJmsListenerContainerFactoryConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jms.annotation.EnableJms;
import org.springframework.jms.config.DefaultJmsListenerContainerFactory;
import org.springframework.jms.support.converter.MappingJackson2MessageConverter;
import org.springframework.jms.support.converter.MessageConverter;
import org.springframework.jms.support.converter.MessageType;

@EnableJms
@Configuration
public class JmsConfiguration
{
    @Bean
    public DefaultJmsListenerContainerFactory myFactory(DefaultJmsListenerContainerFactoryConfigurer configurer)
    {
        DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
        factory.setMessageConverter(jacksonJmsMessageConverter());
        return factory;
    }

    @Bean // Serialize message content to json using TextMessage
    public MessageConverter jacksonJmsMessageConverter()
    {
        MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
        converter.setTargetType(MessageType.TEXT);
        converter.setTypeIdPropertyName("_type");
        return converter;
    }
}
yiliuTo commented 3 years ago

Hi @khauser , this error is due to if you want to use the "_type" property, you need also set it in the sending side. Currently the message doesn't contain this property as below: image

And as for why it can work in the older version, that's because in version 2.3.5, the JmsTemplate doesn't pick up your message converter bean, so it actually doesn't work. You can debug into the function JmsTemplate.getRequiredMessageConverter and see the actual message converter is the default one provided by Spring Jms. From version 3.2.0, we modified the auto-configuration so that the message converter bean can be picked up by JmsTemplate.

khauser commented 3 years ago

Hi @yiliuTo, thanks for the explanation. I will now try to remove the JmsConfiguration as the converter wasn't used in the past.