web-dev-qa-db-fra.com

ArrayOutOfBoundsException sur la création de Bean lors de l'utilisation de Java 8 constructions

J'obtiens un ArrayIndexOutOfBoundsException au démarrage du service (création de bean) lorsque j'utilise Java 8 fonctionnalités.

Java 8 a été installé et fonctionne. Le code se compile correctement. Au démarrage du service, le service n'écoute pas le port car les beans ne sont pas créés. Quand je change le code (enlève Java 8 constructions) le service démarre et tout fonctionne bien.

Voici le code que j'utilise (le code de travail pour lequel le service démarre):

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

Même code en utilisant Java 8 constructions:

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

Le bean pour la classe contenant ce morceau de code est créé à l'aide de l'analyse des composants.

Voici le message d'exception lorsque le deuxième bloc de code est utilisé à la place du premier:

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

Ce qui n'a pas de sens pour moi, c'est pourquoi le code à l'intérieur d'une fonction (qui n'est pas le constructeur de la classe du bean) est couvert lors de la création du bean. Je pose cette question, car l'exception n'est pas là lorsque j'utilise la boucle for normale au lieu du flux parallèle. Un ArrayOutOfBoundsException ne devrait pas se produire lorsque la fonction est appelée et que ce code est réellement utilisé.

Comment puis-je réparer ça?

29
akshitBhatia

Quelle version de Spring utilisez-vous? Vous devez mettre à niveau vers Spring 4 pour utiliser Java 8 expressions lambda.

53
vasekt

J'ai récemment trouvé un bogue lors de l'utilisation de Spring 3.0.5, qui semble être corrigé dans 4.0.5. Voici les détails.

Si vous avez une classe qui a un constructeur paramétré et a également une méthode qui utilise une expression lambda (introduite dans Java 8), alors une ArrayIndexOutOfException se produit lors de la création d'un bean pour cette classe.

16
Ash