Si je mets une expression Java 8 Lambda dans un service REST, il se bloque. Si je supprime l'expression lambda, cela fonctionne. Peu importe si j'utilise l'expression lambda ou non. La simple existence du lambda est suffisante pour provoquer un crash. Tout le reste lié à Java 8 semble fonctionner.
Ci-dessous mon code (simplifié):
@Path("finance")
public class FinanceRest {
@GET
@Produces("text/plain")
public String speak() {
return "Hello world.";
}
private void lambdaFunction(Predicate<Account> predicate) {
// Any lambda will cause problems, no matter how simple
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
Stream<Integer> onlyOdds = numbers.stream().filter(n -> n%2 != 0);
}
}
Comme vous pouvez le voir dans le code ci-dessus, la simple existence d'une expression lambda provoquera un échec. Dès que je retire le lambda, cela fonctionne bien. Les autres éléments de Java 8 sont corrects (par exemple, le paramètre d'entrée "Predicate").
Le message d'erreur que je reçois est le suivant: Java.lang.ArrayIndexOutOfBoundsException: 25980
J'ai essayé ceci sur Tomcat 7 et 8 en utilisant Java 8. J'utilise les fichiers jax-rs standard de JavaEE 6 ... en d'autres termes, mon fichier POM contient ceci:
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-web-api</artifactId>
<version>6.0</version>
<scope>provided</scope>
</dependency>
Toute aide serait appréciée Merci.
Le message d'erreur exact (sur Glassfish 4.0 ... j'ai essayé à la fois Tomcat et Glassfish) est le suivant:
Java.lang.ArrayIndexOutOfBoundsException: 52264 à Org.objectweb.asm.ClassReader.readClass (ClassReader.Java:2015) à Org.objectweb.asm.ClassReader.accept (ClassReader.Java:2015) à Org.objectweb.asm.ClassReader.accept (ClassReader.Java:46. ) à org.objectweb.asm.ClassReader.accept (ClassReader.Java:425) à org.glassfish.hk2.classmodel.reflect.Parser $ 5.on (Parser.Java:362) sur com.Sun.enterprise.v3.server.ReadableArchiveScannerAdapter.handleEntry (ReadableArchiveScannerAdapter.Java:165) sur com.Sun.enterprise.v3.server.ReçuArchiveScannerAdapter.onSelectedEntries (ReadableArchiveScannerAdapter.Java:127) À org.glassfish.hk2.classmodel.reflect.Parser.doJob (Parser.Java:347) à À Org.glassfish.hk2. classmodel.reflect.Parser.access 300 $ (analyseur.Java:67) à org.glassfish.hk2.classmodel.reflect.Parser 3 $ .call (Parser.Java:306) [. .] à org.glassfish.hk2.classmodel.reflect.Parser $ 3.call (Parser.Java:295) à Java.uti l.concurrent.FutureTask.run (FutureTask.Java:266) à Java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.Java:1142) à Java.util .concurrent.ThreadPoolExecutor $ Worker.run (ThreadPoolExecutor.Java:617) à Java.lang.Thread.run (Thread.Java:744)
J'ai trouvé la solution! J'utilisais Jersey 1.17.1. Quand j'ai mis à jour à 2.7 cela a fonctionné. Mon fichier pom avait les éléments suivants:
<dependency>
<groupId>com.Sun.jersey</groupId>
<artifactId>jersey-bundle</artifactId>
<version>1.17.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.Sun.jersey</groupId>
<artifactId>jersey-servlet</artifactId>
<version>1.17.1</version>
<scope>compile</scope>
</dependency>
J'ai enlevé ceux-ci et ajouté:
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>2.7</version>
</dependency>
Et bien sûr, j'ai dû modifier le fichier web.xml pour avoir:
<servlet>
<servlet-name>javax.ws.rs.core.Application</servlet-name>
</servlet>
<servlet-mapping>
<servlet-name>javax.ws.rs.core.Application</servlet-name>
<url-pattern>/rs/*</url-pattern>
</servlet-mapping>
Maintenant tout fonctionne bien. La question est la suivante: Pourquoi les expressions lambda échouaient-elles encore lorsque je les ai supprimées de la classe REST et les ai placées dans une classe non-REST? Le fait que j’incluais Jersey 1.x était suffisant pour provoquer un plantage lorsqu’on utilisait des expressions lambda (qu’il s’agisse ou non d’un service REST réel). Quoi qu'il en soit, je suis heureux que le projet fonctionne à nouveau. J'avais eu envie de passer de toute façon à la dernière version de jax-rs & Jersey, donc cela m’a obligé à le faire (cela m’a coûté plusieurs heures de travail et je dois expliquer au "maître SCRUM" Si je peux seulement comprendre pourquoi Jersey 2 renvoie du code XML alors que je lui ai dit de renvoyer JSON, je serai de retour sur la bonne voie.
Merci à tous pour votre aide!
Jersey 1.19 est compatible avec JDK 1.8.0. Reportez-vous à Jersey 1.19 Résumé de la versionPrise en charge de JDK8 dans Jersey 1.19Remballer ASM dans Jersey 1.19
Supprimez asm-3.1.jar, car jersey-server-1.19.jar contient asm 5.0 remballé.
Le stacktrace montre que la classe org.objectweb.asm.ClassReader.readClass
donne une exception. Je suppose que c'est un analyseur syntaxique que Glassfish utilise en interne.
Une des raisons pour lesquelles il se bloque est qu’il n’est pas configuré pour gérer correctement l’entrée donnée. Dans ce cas, l'entrée donnée est une expression lambda et elle ne sait pas comment la gérer.
Vous devrez rechercher le support Java 8 bytecode (lambda) pour Glassfish et Tomcat. Si ce n'est pas le problème, il peut s'agir d'un bogue de l'analyseur utilisé en interne.
J'ai dû mettre à niveau spring à 4.3.6.RELEASE et junit à 4.12 avant de supprimer cette erreur lorsque j'essayais d'exécuter un test Junit avec Java 1.8 après avoir introduit lamdas.
En plus de toutes les autres réponses,
Sur mon système, ce problème est survenu à Glassfish 4.0(build 89)
Solution;
J'ai mis à niveau
Glassfish to 4.1(build 13)
et le problème a été résolu.