martes, 25 de julio de 2017

JEE & JSF 2on Part: Weld dependencies

Introduction


To show formatted text Hilite is used



Our goal is to configure an Eclipse Maven JSF2 2.2 and CDI with Tomcat.

Weld reports a great problem for servlet containers :



  1. NO SESSION SCOPED BEANS can be used,
  2. NO @EJB INJECTION can be used.
  3. NO @PersistentContext INJECTION can be used.
  4. NO TRANSACTIONAL EVENTS can be used.
So the previous example where a @SessionScoped bean was defined SHOULD NOT WORK (OR MAYBE IT CAN WORK)



Defining Maven dependencies



As mentioned in BalusC Blog these dependencies will be referenced :


  1.  weld-servlet-shaded.jar (requiered)
  2.  validation-api.jar (optional for bean validation)
  3.  hibernate-validator.jar (optional for bean validation)

Our pom.xml file may be this one


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
<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>org.ximodante.jsf</groupId>
  <artifactId>JSFv02</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>war</packaging>
  <name>JSFv02</name>
  <description>JSF 2.2 &amp; CDI</description>
 
  <properties>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <failOnMissingWebXml>false</failOnMissingWebXml>
  </properties>
  
  <dependencies>
     
    <!-- Servlet 3.1 -->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
      <scope>provided</scope>
    </dependency>
    
    <!--  JSF 2.2 API -->
    <dependency>
     <groupId>com.sun.faces</groupId>
     <artifactId>jsf-api</artifactId>
     <version>2.2.14</version>
    </dependency>

    <!--  JSF 2.2 Implementation -->
    <dependency>
     <groupId>com.sun.faces</groupId>
     <artifactId>jsf-impl</artifactId>
     <version>2.2.14</version>
    </dependency>

    <!--  Primefaces -->
    <dependency>
     <groupId>org.primefaces</groupId>
     <artifactId>primefaces</artifactId>
     <version>6.1</version>
    </dependency>

    <!--  Primefaces Themes -->
    <dependency>
     <groupId>org.primefaces.extensions</groupId>
     <artifactId>all-themes</artifactId>
     <version>1.0.8</version>
     <type>pom</type>
    </dependency>
    
    <!-- Weld CDI for Tomcat (does not fulfill all capabilities !!!) -->
    <dependency>
      <groupId>org.jboss.weld.servlet</groupId>
      <artifactId>weld-servlet-shaded</artifactId>
      <version>3.0.0.Final</version>
    </dependency>
    
    <!-- Validation API Optional -->
    <dependency>
      <groupId>javax.validation</groupId>
      <artifactId>validation-api</artifactId>
      <version>2.0.0.CR3</version>
    </dependency>
        
    <!-- Hibernate Bean Validator Optional -->
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-validator</artifactId>
      <version>5.4.1.Final</version>
    </dependency>
    
  </dependencies> 
  
</project>



Creating additional files



These files are our candidates for being created in our webapp folder:

  1. META-INF/context.xml (not necessary for Mojarra version > 2.2.11 ( using now 2.2.14)
  2. WEB-INF/beans.xml (empty file)
NOTE: I have encountered an error on Maven reporting that failed to read artifact descriptor for hibernate-validator dependency. There are different solutions to this issue is in stackoverflow and this other one stackoverflow.


Updating existing files


As mentioned above we SHOULD NOT use CDI @SessionScoped Beans with Tomcat, (we could use @ViewScoped instead .... but for now I will only change the @SessionScoped reference of this dependence to Weld javax.enterprise.context.SessionScoped)

The new annotation replacement for @ManagedBean is @Named according to Weld

But our class must implement Serializable interface in order to avoid this error

Managed bean KeyboardBean which declares a passivating scope SessionScoped must be passivation 

 capable [JSR-346 §6.6.5]

Our class KeyboardBean will be now:


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package org.ximodante.jsf;

//import javax.faces.bean.ManagedBean;
//import javax.faces.bean.SessionScoped;
import javax.inject.Named;
import javax.enterprise.context.SessionScoped;
import java.io.Serializable;



//@ManagedBean
@Named
@SessionScoped

public class KeyboardBean implements Serializable {
   
 private static final long serialVersionUID = 1L;
 
 private String value="12345";
 
 public String getValue() {
  System.out.println("KeyboardBean::reading value: " + value);
        
        return value;
    }
    public void setValue(String value) {
     System.out.println("KeyboardBean::setting value: " + value);
        
        this.value = value;
   }    
}


Let's execute as last post Run As - Run on Server, select tomcat and our URL is:

http://localhost:8080/JSFv01/index.jsf 

And everything should go as last post




JEE & JSF 1st Part: Creating a Maven project

Java EE & JSF 1st Part 

Introduction

To show formatted text Hilite is used



Our goal is to configure an Eclipse Maven JSF2 2.2.


Prerequisites


It is needed:
  1. Eclipse JEE (Neon v.3)
  2. Tomcat (v.9)

Steps in Eclipse:


1. Create un new maven project (File-New-Other-Maven-Maven Project)

2. Choose Create a simple project (skip archetype selection) y Next


3. In Group id it may be the package name as org.ximodante.jsf.  Both for artifact Id.  and Name  the name of the project is supplied JSFv01, and for packaging a war. A description is interesting . And finally Finish




4. Let's modify the generated file pom.xml as follows.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
<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>org.ximodante.jsf</groupId>
  <artifactId>JSFv01</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>war</packaging>
  <name>JSFv01</name>
  <description>JSF first project</description>
  
  <properties>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <failOnMissingWebXml>false</failOnMissingWebXml>
  </properties>
  
  <dependencies>
     
    <!-- Servlet 3.1 -->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
      <scope>provided</scope>
    </dependency>
    
    <!--  JSF 2.2 API -->
    <dependency>
     <groupId>com.sun.faces</groupId>
     <artifactId>jsf-api</artifactId>
     <version>2.2.14</version>
    </dependency>

    <!--  JSF 2.2 Implementation -->
    <dependency>
     <groupId>com.sun.faces</groupId>
     <artifactId>jsf-impl</artifactId>
     <version>2.2.14</version>
    </dependency>

    <!--  Primefaces -->
    <dependency>
     <groupId>org.primefaces</groupId>
     <artifactId>primefaces</artifactId>
     <version>6.1</version>
    </dependency>

    <!--  Primefaces Themes -->
    <dependency>
     <groupId>org.primefaces.extensions</groupId>
     <artifactId>all-themes</artifactId>
     <version>1.0.8</version>
     <type>pom</type>
    </dependency>
  </dependencies>
  
  <!--  Needed repository only for old vesioons of Primefaces 
  <repositories>
    <repository>
      <id>primefaces-repository</id>
      <name>Primefaces repository</name>
      <url>http://repository.primefaces.org</url>
    </repository>
 </repositories>
 --> 
  
</project>

No repository entry is requiered for new versions of Primefaces.

5. It is importat to note these changes.
  <maven.compiler.source>1.8</maven.compiler.source>
 <maven.compiler.target>1.8</maven.compiler.target>  For java 1.8

  <failOnMissingWebXml>false</failOnMissingWebXml>  To get rid of web.xml file.

  Dependencies for servlet 3.1, jsf api and implementation, Primefaces are supplied

  For Servlet 3.1 mentioning <scope>provided</scope> to use this dependencies for compiling purposes. But Tomcat dow not need then for the war deployment. Usually all modern servers have tem included. 

6. Let's download all dependencies from Maven:Right click on our Project Maven -Update Project


Class creation and project execution


Let's create our package org.ximodante.jsf  in src/main/java 

Following instructions from itcuties   let's createw a class called KeyboardBean

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
package org.ximodante.jsf; 

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;


@ManagedBean
@SessionScoped
public class KeyboardBean {
   private String value;
   public String getValue() {
       System.out.println("KeyboardBean::reading value: " + value);
        
       return value;
   }
   public void setValue(String value) {
       System.out.println("KeyboardBean::setting value: " + value);
        
       this.value = value;
   }    
}

Let's create file index.xhtml in src/main/webapp


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
<html xmlns="http://www.w3.org/1999/xhtml" 
    xmlns:h="http://java.sun.com/jsf/html" 
    xmlns:f="http://java.sun.com/jsf/core" 
    xmlns:p="http://primefaces.org/ui">  
    <h:head>  
    </h:head>  
      
    <h:body>  
       <h:form>  
           <p:panel header="Keyboard Demo">    
               <p:keyboard value="#{keyboardBean.value}"/>  
             </p:panel>
             <p:commandButton value="Submit"/>
       </h:form>
    </h:body>  
</html>

In src/main/webapp the WEB-INF folder should be created and added the skeleton of file faces-config.xml as mentioned in coreservlets

1
2
3
4
5
6
7
8
<?xml version="1.0" encoding="UTF-8"?>
<faces-config 
              xmlns="http://xmlns.jcp.org/xml/ns/javaee" 
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
              xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd"
              version="2.2">  

</faces-config>

Let's update our project Right Click on our project - Build Project


Executing the project


I know 2 ways of executing the project:


Mode 1:

Right-click the project - Run As - Run on Server, select tomcat and the URL is:

http://localhost:8080/JSFv01/index.jsf

(Caution: when executing this url is filled in the browser http://localhost:8080/JSFv01 and NOT http://localhost:8080/JSFv01/index.jsf giving an error. The correct URL should be supplied)

This error could be avoided if the file web.xml had been used, that redirects to our welcome page. But for the moment we want to get rid of this file. See comments of Arun Gupta for more details


Mode 2:

In the Project Explorer window, go to  Deployed Resources  (folder) -> webapp (folder)

Right-click the file index.xhtm (or whatever xhtml file you want to execute)  - Run As - Run on Server, select tomcat

Observe the URL that automatically appears is:

http://localhost:8080/JSFv01/faces/index.xhtml


After executing ...
In the console, the displayed log of the values typed in the field can be seen.

KeyboardBean::reading value: null
KeyboardBean::reading value: null
KeyboardBean::setting value: uuu

JEE & JSF16th Part: Creating an abstraction view layer to JSF components and Forms (5/5). Frequent problems

1. ERROR #1: Using a bean that does not exists In the previos entry we used this facelet file: 1 2 3 4 5 6 7 8 9 10 11 1...