Spring Boot RabbitMQ Ошибка исключения нулевого указателя

Я использую RabbitMQ с Spring Boot для обмена сообщениями между двумя службами. Я могу получить сообщение и отформатировать его, но когда я вызываю класс службы в методе onMessage, я получаю ошибку исключения нулевого указателя. Вот мой класс слушателя сообщения, который получает сообщение

public class QueueListener implements MessageListener{
    @Autowired
    private QueueProcessor queueProcessor;

    @Override
    public void onMessage(Message message) {
        String msg = new String(message.getBody());
        String output = msg.replaceAll("\\\\", "");
        String jsonified = output.substring(1, output.length()-1);

        JSONArray obj = new JSONArray(jsonified);

        queueProcessor.processMessage(obj);
    }
}

Вызов метода processMessage генерирует исключение нулевого указателя

Может кто-то указать мне, что я делаю неправильно?

1 ответ

Решение

Я обнаружил, что проблема была в классе RabbitMqConfig. Вот код, который вызывал ошибку:

@Configuration
public class RabbitMqConfig {
private static final String QUEUE_NAME = "my.queue.name";

    @Bean
    public ConnectionFactory connectionFactory() {
    CachingConnectionFactory connectionFactory = new CachingConnectionFactory("<url.to.rabbit>");
    connectionFactory.setUsername("<username>");
    connectionFactory.setPassword("<password>");
    return connectionFactory;;
    }

    @Bean
    public Queue simpleQueue() {
        return new Queue(QUEUE_NAME);
    }

    @Bean
    public MessageConverter jsonMessageConverter(){
        return new Jackson2JsonMessageConverter();
    }

    @Bean
    public RabbitTemplate rabbitTemplate() {
        RabbitTemplate template = new RabbitTemplate(connectionFactory());
        template.setRoutingKey(QUEUE_NAME);
        template.setMessageConverter(jsonMessageConverter());
        return template;
    }

    @Bean
    public SimpleMessageListenerContainer userListenerContainer() {
        SimpleMessageListenerContainer listenerContainer = new SimpleMessageListenerContainer();
        listenerContainer.setConnectionFactory(connectionFactory());
        listenerContainer.setQueues(simpleQueue());
        listenerContainer.setMessageConverter(jsonMessageConverter());
        listenerContainer.setMessageListener(new QueueListener());
        listenerContainer.setAcknowledgeMode(AcknowledgeMode.AUTO);
        return listenerContainer;
    }
}

Линия listenerContainer.setMessageListener(new QueueListener()); был источником ошибки. Я решил это с помощью Autowiring класса вместо использования нового. Вот рабочий код

@Configuration
public class RabbitMqConfig {
private static final String QUEUE_NAME = "my.queue.name";

    @Autowired
    private QueueListener queueListener;

    @Bean
    public ConnectionFactory connectionFactory() {
        CachingConnectionFactory connectionFactory = new CachingConnectionFactory("<url.to.rabbit>");
        connectionFactory.setUsername("<username>");
        connectionFactory.setPassword("<password>");
        return connectionFactory;
    }

    @Bean
    public Queue simpleQueue() {
        return new Queue(QUEUE_NAME);
    }

    @Bean
    public MessageConverter jsonMessageConverter(){
        return new Jackson2JsonMessageConverter();
    }

    @Bean
    public RabbitTemplate rabbitTemplate() {
        RabbitTemplate template = new RabbitTemplate(connectionFactory());
        template.setRoutingKey(QUEUE_NAME);
        template.setMessageConverter(jsonMessageConverter());
        return template;
    }

    /*@Bean
    public SimpleMessageListenerContainer userListenerContainer() {
        SimpleMessageListenerContainer listenerContainer = new SimpleMessageListenerContainer();
        listenerContainer.setConnectionFactory(connectionFactory());
        listenerContainer.setQueues(simpleQueue());
        listenerContainer.setMessageConverter(jsonMessageConverter());
        listenerContainer.setMessageListener(queueListener);
        listenerContainer.setAcknowledgeMode(AcknowledgeMode.AUTO);
        return listenerContainer;
    }
}

Надеюсь, это поможет кому-то еще

Убедитесь, что QueueListener это component класс или service класс, которым может управлять Spring IoC. В противном случае класс конфигурации не может сделать этоbean прямо из коробки, поскольку это обычный Java-класс, который должен находиться в контейнере @runtime.

Итак, когда ты пишешь new QueueListener() в классе конфигурации yr, то класс Java отсутствует в SpringContext в то время, когда создается экземпляр класса конфигурации и, следовательно, null.

Надеюсь, это поможет прояснить некоторые из этих проблем!

Другие вопросы по тегам