2

I have this small project...

In file 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());
    }
}

In file 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";
        }
    }

}

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

Run the site using mvn jetty:run. I am using Maven version 3.2.1.

The problem

If I have the boolean literal in HelloBackingBean be true, nothing shows up when I visit localhost:8080/faces/hello.xhtml. However, if I change it to false (as it is given above), I see "Hello from string literal," as expected.

This leads me to conclude that somehow the very presence of a lambda is causing MyFaces/JSF to misbehave. This is further corroborated by localhost:8080/, which is powered by the Root class, which uses a lambda to get its message and works as expected.

My question is: why is my lambda usage not working in this project? Furthermore, why do I not get some kind of error message? Am I not checking the right places? I see no activity in the terminal when I access localhost:8080/faces/hello.xhtml.

Also worth noting that I assume javac will completely leave out code inside an if (false) block. If it doesn't... well... then I have even less idea how this is working or what's going wrong...

Tiny
  • 27,221
  • 105
  • 339
  • 599
Dan Passaro
  • 4,211
  • 2
  • 29
  • 33
  • What JDK 8 (and MyFaces, AppServer) version are you using? Try the latest version, if it is not. – Tiny Dec 02 '14 at 19:44
  • I'm using MyFaces 2.2.5 (as listed in the POM). I'm at work so I can't check what Jetty version it uses exactly, but it's also relatively recent, given the Maven Jetty plugin version is from 2014-11-12 (also in POM). And since I'm at work I can't check my JDK version, but it's relatively recent and supports lambdas given the servlet response which used a lambda worked. Were you able to get the example running with no problems? – Dan Passaro Dec 02 '14 at 20:01
  • In my small/general tests, it works fine on GlassFish Server 4.1 provided that it uses JDK 8u20 or higher (otherwise, calling remote EJBs has some problems - [here it is](http://stackoverflow.com/q/24519381/1391249)). It also goes fine on Tomcat 8.x (in my case, it is 8.0.9.0) with Spring framework. I am not familiar with other servers. I am currently using JDK 8u25. – Tiny Dec 02 '14 at 20:10
  • 1
    I tried your same lambda expression in a JSF managed bean, a CDI managed bean and in an EJB alternatively in my real application on GlassFish 4.1 (having JSF 2.2.8-02). The same tried on Tomcat 8.0.9.0 (having Spring 4.0 GA, JSF 2.2.8-02) in a Spring managed bean as well as in a Spring service. The expression executed successfully in all cases (excluding the fact that EclipseLink has a [bug](https://bugs.eclipse.org/bugs/show_bug.cgi?id=429992) which is scheduled to be fixed in its version 2.6.0. Hence, lambda expressions cannot be used in entity classes for now). Not sure about Eclipse Jetty. – Tiny Dec 02 '14 at 22:15
  • @Tiny I appreciate your feedback. I feel relatively confident that Jetty is okay with lambdas since the non-JSF servlet has a lambda which seems to work correctly. That said since you were able to get the code working in so many situations it seems I'll have to play around with dependency and JDK version numbers as well as different containers when I get home. Again, I really appreciate the feedback. – Dan Passaro Dec 02 '14 at 23:05
  • @Tiny I've swapped out MyFaces for Mojarra and now it works! I appreciate your help; I'm new to JavaEE and I had assumed I configured something improperly. It never occurred to me there might just be a version compatibility issue. I'm also using an apparently ancient JDK version (`java -version` says "1.8.0-b132") so I'll see if updating Java8 will lead to MyFaces working as expected. Thanks again! – Dan Passaro Dec 03 '14 at 02:58

1 Answers1

1

JSF 2.2 is JDK 6 compatible, not JDK 8. But recently a patch was submitted in MYFACES-3945. It was already committed and it will be available when MyFaces 2.2.7 is released, which will be done soon. It should solve your problem.

If you have any doubt or possible bug over MyFaces please send an email to MyFaces users mailing list. If it is a confirmed bug, report it on MyFaces Core issue tracker.

lu4242
  • 2,318
  • 1
  • 15
  • 15