0

I use an old fashion JSP scriptlet code and I have decided to give Facelets a try and migrate my application. I already dislike some things (like the extra work of having to change some of the HTML5 tags that a designer gives me, close them, etc) but the benefits seem worth it. I am finding some problems in the migration, basically I am trying to define a composite component and pass over a List<T extends BasicData> to be displayed.

I am using Netbeans 8.0.2, Apache Tomcat 8.0.3.0 (J2EE 7), JDK 1.8. I am reading Java Server Faces - Introduction by example to get help and examples.

1) I am not sure I have included the right dependencies in Maven, or if I included duplicated functionality with the libraries. Is this the minimum set? (considering I might use some JSTL)

<dependencies>
<dependency>
    <groupId>javax</groupId>
    <artifactId>javaee-web-api</artifactId>
    <version>7.0</version>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>javax.faces</groupId>
    <artifactId>javax.faces-api</artifactId>
    <version>2.2</version>
    <scope>provided</scope>
</dependency>
<dependency>
    <!-- This is the Mojarra Implementation of JSF -->
    <groupId>org.glassfish</groupId>
    <artifactId>javax.faces</artifactId>
    <version>2.2.8-02</version>
    <scope>runtime</scope>
</dependency>

<dependency>
    <groupId>com.sun.faces</groupId>
    <artifactId>jsf-api</artifactId>
    <version>2.1.0-b03</version>
</dependency>
<dependency>
    <groupId>com.sun.faces</groupId>
    <artifactId>jsf-impl</artifactId>
    <version>2.1.0-b03</version>
</dependency>

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>jstl</artifactId>
    <version>1.2</version>
</dependency>

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>servlet-api</artifactId>
    <version>2.5</version>
</dependency>

<dependency>
    <groupId>javax.servlet.jsp</groupId>
    <artifactId>jsp-api</artifactId>
    <version>2.1</version>
</dependency>

<dependency>
    <groupId>com.sun.el</groupId>
    <artifactId>el-ri</artifactId>
    <version>1.0</version>
</dependency>

2) Since JSF 2.0, I am not supposed to need the following fragment in the web.xml. However, when I omit it I don't get the JSF rendered and I only obtain the untreated XML. What am I doing wrong?

<context-param>
    <param-name>javax.faces.PROJECT_STAGE</param-name>
    <param-value>Development</param-value>
</context-param>

<servlet>
    <servlet-name>Faces Servlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>/faces/*</url-pattern>
</servlet-mapping> 

<servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.jsf</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.faces</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.xhtml</url-pattern>
</servlet-mapping>

3) Now the main problem is that my bean doesn't seem to get instantiated. Everything renders fine except that the bean is passed is always null. In fact I can pass any data type (for example a String instead of a List) and it never complains (since whatever I pass is always null and Netbeans apparently does not detect it at compilation time).

index.xhtml

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
                xmlns:h="http://java.sun.com/jsf/html"
                xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
                xmlns:util="http://java.sun.com/jsf/composite/util"
                template="template.xhtml">
    <ui:define name="content">
        <util:visualisationList
            elementList="#{visualisationListController.elements}"/>
    </ui:define>
</ui:composition>

visualisationListController.java

    @Named(value = "visualisationListController")
    @Dependent
    public class VisualisationListController <T extends BasicData> implements Serializable {

        private List<T> elements;
        /**
         * Creates a new instance of visualisationList
         */
        public VisualisationListController() {
           // This is for testing, eventually I would like to get this information from a DB
            System.out.println("constructor");
            elements = new ArrayList<>();
            ComplexData cd = new ComplexData(); // ComplexData EXTENDS BasicData
            cd.setName("ELEMENT 1");
            elements.add((T)cd);
            cd = new ComplexData();
            cd.setName("ELEMENT 2");
            elements.add((T)cd);
        }

        public List<T> getElements() {
            return elements;
        }

        public void setElements(List<T> elements) {
            this.elements = elements;
        } 
    }

visualisationList.xhtml (This renders, but the list is null so nothing is printed)

    <!DOCTYPE html>
    <html lang="en"
          xmlns="http://www.w3.org/1999/xhtml"
          xmlns:h="http://java.sun.com/jsf/html"
          xmlns:cc="http://xmlns.jcp.org/jsf/composite"
          xmlns:c="http://java.sun.com/jsp/jstl/core">

        <!-- INTERFACE -->
        <cc:interface>
            <cc:attribute name="elementList" type="java.util.List" required="true" shortDescription="The list of objects to be displayed"/>
        </cc:interface>

        <!-- IMPLEMENTATION -->
        <cc:implementation>
                    <ul>
                        <c:forEach items="#{cc.attrs.elementList}" var="element">
                            <li>
                                #{element.name}
                            </li>
                        </c:forEach>
                    </ul>
        </cc:implementation>
    </html>

I never read I need a beans.xml as suggested here, and this post does not give me clues either. The bean is supposed to be automatically instantiated. To do some further testing, I have tried the first simple example from the aforementioned book and my bean doesn't get instantiated either. I understand from the book text that the object should be automatically instantiated.

In case there is an error on the way I treat or create the List, I have also tried to use a less complex data (just a String), use @SessionScoped and remove the c:forEach, and it does not work either.

EDIT

The problem is fixed thanks to (once again) BalusC pointer. I had to get information from different sources, so, for convenience, I have compiled the steps I took below. However, it is still not clear my question (1): According to the JSF info page, I only need to include one Maven dependency. But when doing so, I get the following error message:

An Error Occurred:

Could not get component metadata for visualisationList.xhtml. Did you forget to specify <composite:interface>?

viewId=/index.xhtml
location= ...

I have tried several things, including steps in here, unsuccessfully. If I include certain libraries I get:

javax.servlet.ServletException
    javax.faces.webapp.FacesServlet.service(FacesServlet.java:606)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
root cause

java.lang.NullPointerException
    java.util.concurrent.ConcurrentHashMap.putVal(ConcurrentHashMap.java:1011)
    java.util.concurrent.ConcurrentHashMap.putIfAbsent(ConcurrentHashMap.java:1535)

The only thing that worked for me, although I am not sure why, is to include the dependency:

    <dependency>
        <groupId>org.glassfish</groupId>
        <artifactId>javax.faces</artifactId>
        <version>2.2.8-02</version>
        <scope>runtime</scope>
    </dependency>

(Together with the javaee-web-api 6.0 of course)

Only then, I get the result I was expecting from the beginning. However, I don't understand why this dependency has to be included, if TomEE was suppossed to provide it all. Also, I am not sure it means I will use v.2.2 when I have read that EE 6 should only run up to 2.1. Finally, I had to create a beans.xml for this to work, and I am not sure why - Is this only for JSF version <= 2.1?


STEPS I TOOK TO CHANGE TOMCAT TO TOMEE ON NETBEANS

  1. Download TomEE. Install and configure it in Netbeans servers section. (Source)
  2. Edit TomEE server.xml and changed all ports to avoid collision with my old Tomcat.
  3. In server.xml, remove the xpoweredBy and server attributes from the connector:

    (Source)

  4. Then, in bin/catalina.bat change:

    :noJuliConfig
    set "JAVA_OPTS=%JAVA_OPTS% %LOGGING_CONFIG%"
    ...
    :noJuliManager
    set "JAVA_OPTS=%JAVA_OPTS% %LOGGING_MANAGER%"
    

    to:

    :noJuliConfig
    set JAVA_OPTS=%JAVA_OPTS% %LOGGING_CONFIG%
    ... 
    :noJuliManager
    set JAVA_OPTS=%JAVA_OPTS% %LOGGING_MANAGER%
    

    (Source)

  5. Then right click on project - Properties - Run. Change server to TomEE and Java EE version to "Java EE 6 Web" (since the current version of TomEE only accepts JEE 1.6). Dependencies in pom.xml have to be changed accordingly, to version 6:

    <dependency>
        <groupId>javax</groupId>
        <artifactId>javaee-web-api</artifactId>
        <version>6.0</version> <!-- 7.0 (JSF 2.2) or 6.0 (JSF 2.0/2.1) -->
        <scope>provided</scope>
    </dependency>
    ....
    <artifactItem>
         <groupId>javax</groupId>
         <artifactId>javaee-endorsed-api</artifactId>
         <version>6.0</version>
         <type>jar</type>
     </artifactItem>
    

    ....

Now TomEE should work and run the application from Netbeans.


Community
  • 1
  • 1
user1156544
  • 1,532
  • 1
  • 17
  • 40
  • Another related food: http://stackoverflow.com/questions/30128395/identifying-and-solving-javax-el-propertynotfoundexception-target-unreachable (you would have faced this problem when submitting a form). – BalusC Apr 01 '16 at 09:50
  • Many thanks for this! I have installed TomEE but it only supports JEE6 so when I use the dependency for "javaee-web-api" version "6.0" I get all sort of EE packages not found (ServletException, @Dependent...) - I followed http://stackoverflow.com/tags/jsf/info. I thought TomEE already shipped with all that stuff... Am I doing something wrong? – user1156544 Apr 01 '16 at 14:14

0 Answers0