Подтвердить что ты не робот

Выражение Lambda Java 8 в службе REST не работает

Если я поставлю выражение Java 8 Lambda в службе REST, он сработает. Если я удалю выражение лямбда, это сработает. Не имеет значения, пользуюсь ли я лямбда-выражением или нет. Просто существование лямбды достаточно для краха. Все, что связано с Java 8, похоже, работает.

Ниже мой код (упрощенный):

@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);
    }

}

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

Сообщение об ошибке, которое я получаю: java.lang.ArrayIndexOutOfBoundsException: 25980

Я пробовал это на Tomcat 7 и 8, используя Java 8. Я использую стандартный материал jax-rs из JavaEE 6.... другими словами, у моего POM файла есть следующее:

    <dependency>
        <groupId>javax</groupId>
        <artifactId>javaee-web-api</artifactId>
        <version>6.0</version>
        <scope>provided</scope>
    </dependency>

Любая помощь будет оценена по достоинству. Спасибо.

Точное сообщение об ошибке (на Glassfish 4.0... Я пробовал как Tomcat, так и Glassfish):

java.lang.ArrayIndexOutOfBoundsException: 52264 at org.objectweb.asm.ClassReader.readClass(ClassReader.java:2015) в org.objectweb.asm.ClassReader.accept(ClassReader.java:469) at org.objectweb.asm.ClassReader.accept(ClassReader.java:425) at org.glassfish.hk2.classmodel.reflect.Parser $5.on(Parser.java:362) в com.sun.enterprise.v3.server.ReadableArchiveScannerAdapter.handleEntry(ReadableArchiveScannerAdapter.java:165)   в com.sun.enterprise.v3.server.ReadableArchiveScannerAdapter.onSelectedEntries(ReadableArchiveScannerAdapter.java:127)   at org.glassfish.hk2.classmodel.reflect.Parser.doJob(Parser.java:347)   в org.glassfish.hk2.classmodel.reflect.Parser.access $300 (Parser.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.util.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)

4b9b3361

Ответ 1

Я нашел решение! Я использовал Джерси 1.17.1. Когда я обновился до 2.7, он сработал. Мой файл pom имел следующее:

<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>

Я удалил те и добавил:

<dependency>
    <groupId>org.glassfish.jersey.containers</groupId>
    <artifactId>jersey-container-servlet</artifactId>
    <version>2.7</version>
</dependency>

И, конечно, мне пришлось изменить файл web.xml, чтобы:

<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>

Теперь все работает хорошо. Вопрос: Почему лямбда-выражения все еще терпят неудачу, когда я удалял их из класса REST и помещал их в класс non-REST? Просто факт, что я включил Джерси 1.x, был достаточным для краха при использовании лямбда-выражений (независимо от того, была ли задействована реальная служба REST). Но, во всяком случае, я рад, что проект снова работает; Я так и хотел обновиться до последней версии jax-rs и Jersey, так что это заставило меня это сделать (стоило мне несколько часов работы и мне нужно было объяснить "мастеру SCRUM", почему моя оценка отключена (не запустите меня по этой теме). Теперь, если я смогу только выяснить, почему Джерси 2 возвращает XML, когда я сказал ему вернуть JSON, я вернусь в нужное русло.

Спасибо всем за вашу помощь!

Ответ 3

Столбец показывает, что класс org.objectweb.asm.ClassReader.readClass дает исключение. Я полагаю, что это парсер, который Glassfish использует внутри.

Одна из причин, по которой он произошел сбой, заключается в том, что он не настроен правильно обрабатывать данный вход. В этом случае данный ввод является лямбда-выражением, и он не знает, как его обрабатывать.

Вам нужно будет найти поддержку байт-кода Java (lambda) для Glassfish и Tomcat. Если это не проблема, то это может быть ошибка в парсер, который используется внутри.

Ответ 4

Мне пришлось обновить spring до 4.3.6.RELEASE и junit до 4.12, прежде чем я избавился от этой конкретной ошибки при попытке запустить junit-тест с java 1.8 после того, как я представил lamdas.

Ответ 5

В дополнение ко всем другим ответам,

В моей системе эта проблема возникает на Glassfish 4.0(build 89)

Решение

Я обновил Glassfish to 4.1(build 13) и решил эту проблему.