ArrayOutOfBoundsException при создании бинов при использовании конструкций Java 8

20

Я получаю ArrayIndexOutOfBoundsException при запуске службы (создание Bean), когда я использую функции Java 8.

Java 8 настроен и работает. Код правильно компилируется. При запуске службы служба не может прослушивать порт, поскольку бобы не создаются. Когда я меняю код (удаляю java 8 constructs), начинается сервис, и все работает нормально.

Это код, который я использую (рабочий код, для которого запускается сервис):

for (Item itemObject : response) {
    if (itemObject.hasId()) {
        idList.add(String.valueOf(itemObject.Id());
    }
}

Тот же код с использованием конструкций Java 8:

response.parallelStream()
        .filter(itemObject -> itemObject.hasId())
        .map(itemObject -> itemObject.getId())
        .forEach(id -> idList.add(id));

Боб для класса, содержащего этот фрагмент кода, создается с помощью проверки компонентов.

Ниже приведено сообщение об исключении, когда второй кодовый блок используется вместо первого:

Exiting with throwable: java.lang.IllegalArgumentException: org.springframework.beans.factory.BeanDefinitionStoreException: Failed to read candidate component class: URL [jar:file:/workspace/.../GetContainerIdForFcSkuAdapter.class]; nested exception is java.lang.ArrayIndexOutOfBoundsException: 51880
 java.lang.IllegalArgumentException: org.springframework.beans.factory.BeanDefinitionStoreException: Failed to read candidate component class: URL [jar:file:/workspace....Some.class]; nested exception is java.lang.ArrayIndexOutOfBoundsException: 51880

Что для меня не имеет смысла, почему код внутри функции (который не является конструктором класса bean) закрывается при создании компонента. Я спрашиваю об этом, потому что исключения не существует, когда я использую обычный цикл for вместо параллельного потока. Если при вызове функции не возникает ArrayOutOfBoundsException , этот код действительно используется.

Как я могу это исправить?     

задан akshitBhatia 09.06.2015 в 12:12
источник
  • Что такое idList? Во второй версии вы используете parallelStream, чтобы добавлять элементы в этот список из нескольких потоков. Является ли реализация списка используемой поточно-безопасной? Ошибка исчезнет, ​​если вы используете stream () вместо parallelStream ()? –  Jesper 09.06.2015 в 12:15
  • Кроме того, обычным способом получить содержимое потока в списке является List <Something> list = stream.collect (Collectors.toList ()) вместо stream.forEach (o -> list.add (o) , –  Jesper 09.06.2015 в 12:18
  • Я не добавляю из нескольких потоков. Java внутренне разворачивает цикл и распараллеливает. ошибка при использовании пара. Как я уже сказал, блок кода должен выполняться при вызове функции, а не в создании бина. Как этот блок используется и дает ArrayIndexOutOfBounds при запуске службы. Пожалуйста, посмотрите мой ответ ниже и скажите мне, думаете ли вы, что это может быть причиной –  akshitBhatia 09.06.2015 в 12:28

2 ответа

35

Какую версию Spring вы используете? Вам нужно обновить до Spring 4, чтобы использовать лямбда-выражения Java 8.

    
ответ дан vasekt 13.07.2015 в 10:48
источник
  • Да, <org.springframework-version> 4.0.X.RELEASE </org.springframework-version> работает с java 8. –  Buminda 01.01.2016 в 22:10
10

Недавно я обнаружил ошибку при использовании Spring 3.0.5, которая, как представляется, исправлена ​​в 4.0.5. Вот подробности.

Если у вас есть класс с параметризованным конструктором, а также метод, который использует выражение lambda (введенное в Java 8), тогда при создании компонента для этого класса возникает ArrayIndexOutOfException.

    
ответ дан Ash 05.06.2016 в 17:56
источник
  • На самом деле это не ошибка. Spring 3 не полностью поддерживает Java 8, поэтому использование Lambdas с Spring 3.0.5 является ошибкой пользователя, а не ошибкой Spring. –  stefan.m 17.10.2016 в 10:44
  • Я просто столкнулся с этим, и это казалось ужасно странным. Это произошло, как вы говорите, когда я добавил параметр в конструктор bean. Я использовал forEach в нескольких местах. Я не думаю, что когда-либо делал бы эту связь, что forEach в любом месте класса нарушал бы свой экземпляр bean-компонента с исключением ограничений границ массива. Ну ладно, спасибо, переполнение стека! –  botimer 16.11.2016 в 00:18
  • вы очистили меня от кошмарной головной боли! Благодаря ! –  Guillaume 03.01.2017 в 14:13