Sqslistener string index out of bounds проблема

Я сталкиваюсь с действительно странной проблемой при попытке использовать аннотацию @SQSListener из модуля Spring Cloud. Вот мой метод слушателя:

@SqsListener(value = "myproject-dev-au-error-queue")
public void listenPhoenix(String message) throws IOException {

    logger.info(message);
 }

Однако как только я запускаю проект, он начинает читать сообщения из очереди и выдает следующую ошибку:

Exception in thread "simpleMessageListenerContainer-4" Exception in thread "simpleMessageListenerContainer-6" Exception in thread "simpleMessageListenerContainer-9" Exception in thread "simpleMessageListenerContainer-10" java.lang.StringIndexOutOfBoundsException: String index out of range: -1
    at java.lang.String.substring(String.java:1931)
    at org.springframework.cloud.aws.messaging.core.QueueMessageUtils.getNumberValue(QueueMessageUtils.java:93)
    at org.springframework.cloud.aws.messaging.core.QueueMessageUtils.getMessageAttributesAsMessageHeaders(QueueMessageUtils.java:80)
    at org.springframework.cloud.aws.messaging.core.QueueMessageUtils.createMessage(QueueMessageUtils.java:56)
    at org.springframework.cloud.aws.messaging.listener.SimpleMessageListenerContainer$MessageExecutor.getMessageForExecution(SimpleMessageListenerContainer.java:375)
    at org.springframework.cloud.aws.messaging.listener.SimpleMessageListenerContainer$MessageExecutor.run(SimpleMessageListenerContainer.java:336)
    at org.springframework.cloud.aws.messaging.listener.SimpleMessageListenerContainer$SignalExecutingRunnable.run(SimpleMessageListenerContainer.java:392)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

С проблемной частью, находящейся в назначении переменной класса QueueMessageUtils модуля spring-cloud-aws-messaging numberType:

private static Object getNumberValue(MessageAttributeValue value) {
    String numberType = value.getDataType().substring("Number".length() + 1);

    try {
        Class<? extends Number> numberTypeClass = Class.forName(numberType).asSubclass(Number.class);
        return NumberUtils.parseNumber(value.getStringValue(), numberTypeClass);
    } catch (ClassNotFoundException var3) {
        throw new MessagingException(String.format("Message attribute with value '%s' and data type '%s' could not be converted into a Number because target class was not found.", value.getStringValue(), value.getDataType()), var3);
    }
}

Кто-нибудь видел это раньше, и если да, есть ли способ исправить это?

P.S: Поскольку меня не особо интересуют атрибуты сообщения, я бы не возражал, если бы они были полностью проигнорированы.

Заранее спасибо.

0
0
577
1

Ответы 1

Исключение в данном коде выбрасывается из следующей строки.

String numberType = value.getDataType().substring("Number".length() + 1);

Согласно документации в AWS JAVA SDK, он объясняет, как работает функция getDataType() (см. эта ссылка). Согласно документации, он вернет одно из следующих значений.

  • Нить

  • Число

  • Двоичный

Amazon SQS supports the following logical data types: String, Number, and Binary. For the Number data type, you must use StringValue.

Теперь, когда вы вызываете value.getDataType(), он вернет одно из указанных выше значений. Предполагая, что это "Number", вы пытаетесь получить его substring, начиная с индекса 6 (где "Number".length() + 1 = 6)

Но в строке, возвращаемой value.getDataType(), такого индекса нет. Следовательно, это вызовет исключение java.lang.StringIndexOutOfBoundsException.

Как решение для этого вы можете просто использовать следующее вместо получения его подстроки.

String numberType = value.getDataType();

Да, проблема в том, что этот метод является частью модуля обмена сообщениями Spring Cloud. Я поднял проблему в их репозитории на github: github.com/spring-cloud/spring-cloud-aws/issues/374

Danny Petrunov 14.09.2018 10:01

@DannyPetrunov Пожалуйста, держите нас в курсе любых решений. Однажды я реализовал это с помощью AWS Java SDK и использовал именно этот метод. У меня это сработало. Получение подстроки этого и попытка решить это не похоже на хорошую практику imo

Keet Sugathadasa 14.09.2018 16:11

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