Лямбда в MyFaces @ManagedBean вызывает отсутствие / странное поведение

У меня есть этот небольшой проект ...

В файле src/main/java/com/mycompany/mavenproject2/Root.java:

package com.mycompany.mavenproject2;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.function.Supplier;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/")
public class Root extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request,
            HttpServletResponse response)
            throws IOException {

        Supplier<String> welcomeMsg = () -> "Hello world! I'm a lambda.";
        PrintWriter writer = response.getWriter();
        writer.println(welcomeMsg.get());
    }
}

В файле src/main/java/com/mycompany/mavenproject2/HelloBackingBean.java:

package com.mycompany.mavenproject2;

import java.util.function.Supplier;
import javax.faces.bean.ManagedBean;

@ManagedBean
public class HelloBackingBean {

    public String getMessage() {
        if (false) {
            Supplier<String> msg = () -> "Hello from a lambda";
            return msg.get();
        } else {
            return "Hello from string literal";
        }
    }

}

В файле src/main/webapp/hello.xhtml:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
      xmlns:f="http://xmlns.jcp.org/jsf/core"
      xmlns:c="http://xmlns.jcp.org/jsp/jstl/core">

    <h:head>
        <title>Test Page</title>
    </h:head>
    <h:body>
        <p>#{helloBackingBean.message}</p>
    </h:body>
</html>

In pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
                             http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.mycompany</groupId>
    <artifactId>mavenproject2</artifactId>
    <version>0.1</version>
    <packaging>war</packaging>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-api</artifactId>
            <version>7.0</version>
            <scope>provided</scope>
        </dependency>

        <!-- JSF implementation -->        
        <dependency>
            <groupId>org.apache.myfaces.core</groupId>
            <artifactId>myfaces-impl</artifactId>
            <version>2.2.5</version>
            <scope>runtime</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.eclipse.jetty</groupId>
                <artifactId>jetty-maven-plugin</artifactId>
                <version>9.2.5.v20141112</version>
                <configuration>
                    <scanIntervalSeconds>1</scanIntervalSeconds>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

Запустите сайт, используя mvn jetty:run. Я использую Maven версии 3.2.1.

Эта проблема

Если у меня есть логический литерал в HelloBackingBean be true, при посещении localhost:8080/faces/hello.xhtml ничего не отображается. Однако, если я изменю его на false (как указано выше), я увижу «Привет из строкового литерала», как и ожидалось.

Это приводит меня к выводу, что каким-то образом само присутствие лямбды приводит к неправильному поведению MyFaces / JSF. Это дополнительно подтверждается localhost:8080/, который поддерживается классом Root, который использует лямбда-выражение для получения своего сообщения и работает должным образом.

У меня вопрос: почему я не использую лямбда-выражения в этом проекте? Кроме того, почему я не получаю сообщения об ошибке? Я не проверяю нужные места? Когда я открываю localhost:8080/faces/hello.xhtml, я не вижу активности в терминале.

Также стоит отметить, что я предполагаю, что javac полностью исключит код внутри блока if (false). Если нет ... ну ... тогда я еще меньше понимаю, как это работает или что не так ...


person Dan Passaro    schedule 30.11.2014    source источник
comment
... почему голос против?   -  person Dan Passaro    schedule 30.11.2014
comment
Какую версию JDK 8 (и MyFaces, AppServer) вы используете? Попробуйте последнюю версию, если ее нет.   -  person Tiny    schedule 02.12.2014
comment
Я использую MyFaces 2.2.5 (как указано в POM). Я на работе, поэтому я не могу проверить, какую именно версию Jetty он использует, но она также относительно недавняя, учитывая, что версия плагина Maven Jetty от 2014-11-12 (также в POM). И поскольку я на работе, я не могу проверить свою версию JDK, но она относительно недавняя и поддерживает лямбда-выражения, учитывая ответ сервлета, который использовал лямбда-выражения. Удалось ли вам запустить пример без проблем?   -  person Dan Passaro    schedule 02.12.2014
comment
В моих небольших / общих тестах он отлично работает на GlassFish Server 4.1 при условии, что он использует JDK 8u20 или выше (в противном случае при вызове удаленных EJB-компонентов возникают некоторые проблемы - вот оно). Он также отлично работает на Tomcat 8.x (в моем случае это 8.0.9.0) с фреймворком Spring. Я не знаком с другими серверами. В настоящее время я использую JDK 8u25.   -  person Tiny    schedule 02.12.2014
comment
Я пробовал такое же лямбда-выражение в управляемом bean-компоненте JSF, управляемом bean-компоненте CDI и в качестве альтернативы в EJB в моем реальном приложении на GlassFish 4.1 (с JSF 2.2.8-02). То же самое пробовалось на Tomcat 8.0.9.0 (имеющем Spring 4.0 GA, JSF 2.2.8-02) в управляемом компоненте Spring, а также в службе Spring. Выражение выполнено успешно во всех случаях (за исключением того факта, что EclipseLink содержит ошибку, который планируется исправить в версии 2.6.0. Следовательно, лямбда-выражения пока не могут использоваться в классах сущностей). Не уверен насчет Eclipse Jetty.   -  person Tiny    schedule 03.12.2014
comment
@Tiny Спасибо за отзыв. Я относительно уверен, что Jetty в порядке с лямбдами, поскольку сервлет, отличный от JSF, имеет лямбда, которая, кажется, работает правильно. Тем не менее, поскольку вы смогли заставить код работать во многих ситуациях, мне кажется, что мне придется поиграться с зависимостями и номерами версий JDK, а также с различными контейнерами, когда я вернусь домой. Опять же, я очень ценю отзывы.   -  person Dan Passaro    schedule 03.12.2014
comment
@Tiny Я заменил MyFaces на Mojarra, и теперь он работает! Я ценю вашу помощь; Я новичок в JavaEE и предполагал, что что-то настроил неправильно. Мне никогда не приходило в голову, что это может быть проблема совместимости версий. Я также использую явно древнюю версию JDK (java -version говорит 1.8.0-b132), поэтому я посмотрю, приведет ли обновление Java8 к тому, что MyFaces будет работать должным образом. Спасибо еще раз!   -  person Dan Passaro    schedule 03.12.2014


Ответы (1)


JSF 2.2 совместим с JDK 6, а не с JDK 8. Но недавно патч был представлен в MYFACES-3945. Он уже был зафиксирован и будет доступен, когда выйдет MyFaces 2.2.7, что будет сделано в ближайшее время. Это должно решить вашу проблему.

Если у вас есть какие-либо сомнения или возможная ошибка в MyFaces, отправьте электронное письмо в список рассылки пользователей MyFaces . Если это подтвержденная ошибка, сообщите о ней в системе отслеживания проблем MyFaces Core.

person lu4242    schedule 13.12.2014