My JSF Books/Videos My JSF Tutorials OmniFaces/JSF PPTs
JSF 2.3 Tutorial
JSF Caching Tutorial
JSF Navigation Tutorial
JSF Scopes Tutorial
JSF Page Author Beginner's Guide
OmniFaces 2.3 Tutorial Examples
OmniFaces 2.2 Tutorial Examples
JSF Events Tutorial
OmniFaces Callbacks Usages
JSF State Tutorial
JSF and Design Patterns
JSF 2.3 New Features (2.3-m04)
Introduction to OmniFaces
25+ Reasons to use OmniFaces in JSF
OmniFaces Validators
OmniFaces Converters
JSF Design Patterns
Mastering OmniFaces
Reusable and less-verbose JSF code

My JSF Resources ...

Java EE Guardian
Member of JCG Program
Member MVB DZone
Blog curated on ZEEF
OmniFaces is an utility library for JSF, including PrimeFaces, RichFaces, ICEfaces ...

.

.

.

.

.

.

.

.


[OmniFaces Utilities] - Find the right JSF OmniFaces 2 utilities methods/functions

Search on blog

Petition by Java EE Guardians

Twitter

duminică, 28 decembrie 2014

Test OmniFaces Cache for Render Response Phase

As a JSF developer, you know that the Render Response phase (the sixth phase) is one of the most time-expensive of all JSF phases, next to the Restore View phase (first phase). Well, OmniFaces provides a component, named Cache which is an server-side caching mechanism. Basically, it allows us to cache a piece of markup produced by the JSF renderers. While the OmniFaces showcase provides clear examples of how to use the Cache (<o:cache>) component, this post tries to test how useful is to cache markup on server-side. We can easily intuit that the <o:cache> should speed up the Render Response phase, but that will have an impact over other aspects also, like memory usage.
So, we tried to accomplish this test for a JSF data table, with variable number of records (rows). The table has nine columns, and it looks like this:
...
<h:dataTable value="#{playersBean.data}" var="t" border="1">
  <h:column>
   <f:facet name="header">Ranking</f:facet>                   
   <h:outputText value="#{t.ranking}" style="color:red;"/>                             
  </h:column>
  <h:column>
   <f:facet name="header">Name</f:facet>                       
   <h:outputText value="#{t.player}">
    <f:converter converterId="lowerCaseConverter"/>
   </h:outputText>
  </h:column>
  <h:column>
   <f:facet name="header">Age</f:facet>                       
   <h:outputText value="#{t.age}">
    <f:converter converterId="ageConverter"/>
   </h:outputText>
  </h:column>
  <h:column>
   <f:facet name="header">Birthplace</f:facet>                      
   <h:outputText value="#{t.birthplace}">
    <f:converter converterId="lowerCaseConverter"/>
   </h:outputText>
  </h:column>
  <h:column>
   <f:facet name="header">Residence</f:facet>                      
   <h:outputText value="#{t.residence}">
    <f:converter converterId="lowerCaseConverter"/>
   </h:outputText>
  </h:column>
  <h:column>
   <f:facet name="header">Height</f:facet>
   <h:outputText value="#{t.height}">
    <f:converter converterId="heighConverter"/>
   </h:outputText>
  </h:column>
  <h:column>
   <f:facet name="header">Weight</f:facet>
   <h:outputText value="#{t.weight}">
    <f:converter converterId="weightConverter"/>
   </h:outputText>
  </h:column>
  <h:column>
   <f:facet name="header">Coach</f:facet>                        
   <h:outputText value="#{t.coach}">
    <f:converter converterId="lowerCaseConverter"/>
   </h:outputText>
  </h:column>
  <h:column>
   <f:facet name="header">Born</f:facet>
   <h:outputText value="#{t.born}">               
    <f:convertDateTime pattern="dd.MM.yyyy" />
   </h:outputText>
  </h:column>
</h:dataTable> 
...


This table is useful because it will produce a lot of markup and we can juggle with the number of records (rows) which means that we can easily control the amount of markup. Moreover, this is a fix table, so is a good opportunity to cache its content instead of rendering it at each postback.
We've performed 5 tests without caching and 5 with caching by varying the number of records (rows) at each test, as follows: 500, 1000, 2000, 5000 and 10000 records (rows). For each test, we have performed 5 consecutives postbacks requests (only one request executed at a time, but all 5 executed in the same minute). For each JSF phase, the initial request and the averages times of postbacks were plotted with respect to the JSF phases (the measurements were made using a JSF phase listener and the System.nanoTime()). The initial request is plotted in the left, and the postbacks in the right.

In the chart below, you can see the results for 500 records (rows):


Next, for 1000 records (rows):


Next, for 2000 records (rows):


Next, for 5000 records (rows):


Now, for 10000 records (rows):


Well, the results are pretty clear. The OmniFaces caching was very useful and has a significant impact on server response time. Is true, and normal, that the initial request takes longer when cache is used (since is a extra task in the rendering phase), but the time lost here is won on postbacks.
 The Application Server GlassFish 4 was used, and the AppDynamics revealed the following charts (the very, very small differences that appears between the above values in miliseconds and the below ones are caused by the fact the above values were obtained via System.nanoTime() and the below ones are obtained via AppDynamics, which is a powerful Application Performance Management tool):

·         first, we have the calls per minute - the points at scale 1 represents the initial requests, while the points at scale 5, represents the postbacks for each run, and there are 5 different runs. Between the initial request and the 5 postbacks, there is a minute without requests - this is happening for each run. As you can see, the charts are the "same", only the times of running differs, which is normal. This chart is a prove that the tests were done under the same conditions.


·         next chart shows the average response time for each run. Is obvious that when cache is not used, all averages are bigger than when cached is used.



·         in order to perceive better, let's check the chart that contains the postbacks times sum. Notice that at 10000 records (rows), the cache will speed up the postbacks times sum with more than 3 seconds.


·         below you can see the distribution of the slowest and the fastest responses during 5 postbacks


·         and, the slowest and fastest requests in respect with calls per minute


·         the next chart reveals the total average response time over the whole 5 runs (196 ms faster with cache)


·         is time to see how the memory was distributed over these 5 runs. So, notice that in case of cache the difference between the average utilization of heap memory is only 1%!


For fine-grained conclusion we also may check:

·         the garbage collector usage


·         the memory pools


The test was performed under the following items:

Notice that this test doesn't involve the useBuffer="true" !!!

marți, 23 decembrie 2014

OmniFaces findComponentRelatively(), findComponentInParents() and findComponentInChildren() methods


[OmniFaces utilities] The findComponentRelatively() returns the UI component matching the given client ID search expression relative to the point in the component tree of the given component. For this search both parents and children are consulted, increasingly moving further away from the given component. Parents are consulted first, then children.
[OmniFaces utilities] The findComponentInParents() returns the UI component matching the given client ID search expression relative to the point in the component tree of the given component, searching only in its parents.
[OmniFaces utilities] The findComponentInChildren() returns the UI component matching the given client ID search expression relative to the point in the component tree of the given component, searching only in its children.

Besides the goodies revealed in the Showcase, OmniFaces has a lot of "hidden pearls" that can help us during development of JSF projects. A few days ago I have "discovered" the OmniFaces utilities, which are a collection of utility methods for the JSF API. More precisely, in the org.omnifaces.util.Components I found the findComponentRelatively() method:

public static <C extends UIComponent> C findComponentRelatively
                            (UIComponent component, String clientId) {
 if (isEmpty(clientId)) {
     return null;
 }

 // Search first in the naming container parents of the given component
 UIComponent result = findComponentInParents(component, clientId);

 if (result == null) {
     // If not in the parents, search from the root
     result = findComponentInChildren(getViewRoot(), clientId);
 }

 return (C) result;
}

Well, as the OmniFaces description says, this method "returns the UI component matching the given client ID search expression relative to the point in the component tree of the given component. For this search both parents and children are consulted, increasingly moving further away from the given component. Parents are consulted first, then children."

But, in order to use this method correctly, you must be aware of several aspects:

·         when searching in parents, the search will stop when the component with clientId is found or at the UIViewRoot
·         the search in children is not relatively to the "point in the component tree of the given component", is rather relative to the UIViewRoot
·         actually, the findComponentRelatively() searches the component with clientId ONLY in instances of NamingContainer (which are: HtmlDataTable, HtmlForm, UIData, UIForm, NamingContainer)
·         for accomplish its job, this method uses the findComponentInParents() and findComponentInChildren() methods
·         These methods (findComponentInParents() and findComponentInChildren()) can be called individually, they are not related to findComponentRelatively() method

The findComponentInParents() is listed below:

public static <C extends UIComponent> C findComponentInParents
                          (UIComponent component, String clientId) {

 if (isEmpty(clientId)) {
    return null;
}

for (UIComponent parent = component; parent != null; parent = parent.getParent()) {
     UIComponent result = null;
     if (parent instanceof NamingContainer) {
         try {
             result = parent.findComponent(clientId);
         } catch (IllegalArgumentException e) {
             continue;
         }
     }

     if (result != null) {
         return (C) result;
     }
 }

return null;
}

As documentation says, this method "returns the UI component matching the given client ID search expression relative to the point in the component tree of the given component, searching only in its parents.".

Well, again there are a few aspects to notice here:

·         the first inspected parent is the " given component"
·         the component matching the given clientId is searched ONLY in NamingContainer instances
·         this is NOT recursive search! Is just a parent-traversal algorithm from the " given component" to the UIViewRoot

When findComponentInParents() return null, the findComponentInChildren() is called. The code is listed below:

public static <C extends UIComponent> C findComponentInChildren
                           (UIComponent component, String clientId) {

 if (isEmpty(clientId)) {
     return null;
 }

 for (UIComponent child : component.getChildren()) {

      UIComponent result = null;
      if (child instanceof NamingContainer) {
         try {
             result = child.findComponent(clientId);
         } catch (IllegalArgumentException e) {
             continue;
          }
      }

      if (result == null) {
          result = findComponentInChildren(child, clientId);
      }

      if (result != null) {
          return (C) result;
      }
 }

 return null;
}

As documentation says, this method "returns the UI component matching the given client ID search expression relative to the point  in the component tree of the given component, searching only in its children."

The important things to notice here are:

·         the inspection doesn't start from the " given component", as in the case of findComponentInParents(). It starts from the first child.
·         the component matching the given clientId is searched ONLY in NamingContainer instances
·         this is a recursive method - the recursive process performs a clean traversal of the component's tree (or subtree) by visiting each node in a hierarchical approach.
·         the findComponentRelatively() uses this method to traverse the component tree starting from the UIViewRoot


Each of these three methods uses the JSF, UIComponent.findComponent() which acts as below:


For the sake of completeness, the source code of the findComponent() method from UIComponentBase (extracted from Mojarra implementation) is listed below - is pretty straightforward:
public UIComponent findComponent(String expr) {

 if (expr == null) {
     throw new NullPointerException();
 }

 FacesContext ctx = FacesContext.getCurrentInstance();
 final char sepChar = UINamingContainer.getSeparatorChar(ctx);
 final String SEPARATOR_STRING = String.valueOf(sepChar);

 if (expr.length() == 0) {
     // if an empty value is provided, fail fast.
     throw new IllegalArgumentException("\"\"");
 }

 // Identify the base component from which we will perform our search
 UIComponent base = this;
 if (expr.charAt(0) == sepChar) {
     // Absolute searches start at the root of the tree
     while (base.getParent() != null) {
            base = base.getParent();
     }
     // Treat remainder of the expression as relative
     expr = expr.substring(1);
 } else if (!(base instanceof NamingContainer)) {
            // Relative expressions start at the closest NamingContainer or root
            while (base.getParent() != null) {
                   if (base instanceof NamingContainer) {
                       break;
                   }
            base = base.getParent();
            }
 }

 // Evaluate the search expression (now guaranteed to be relative)
 UIComponent result = null;
 String[] segments = expr.split(SEPARATOR_STRING);
 for (int i = 0, length = (segments.length - 1);
      i < segments.length;
      i++, length--) {
      result = findComponent(base, segments[i], (i == 0));
      // the first element of the expression may match base.id
      // (vs. a child if of base)
      if (i == 0 && result == null &&
          segments[i].equals(base.getId())) {
          result = base;
      }
      if (result != null && (!(result instanceof NamingContainer)) && length > 0) {
          throw new IllegalArgumentException(segments[i]);
      }
      if (result == null) {
          break;
      }
      base = result;
 }

 // Return the final result of our search
 return (result);

}

OmniFaces, internally uses the findComponentRelatively() method. Per example, in the OutputLabel component, OmniFaces uses this method to find the component indicated by the for attribute. Let's check this example:

<?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 id="htmlId"  xmlns="http://www.w3.org/1999/xhtml"
      xmlns:o="http://omnifaces.org/ui"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:f="http://xmlns.jcp.org/jsf/core">
  <h:head id="headId">
    <title>Register Form</title>       
  </h:head>
  <h:body id="bodyId">
      
  <h:form id="registerFormId">
    <h:panelGrid id="panelId" columns="3">    
      <o:outputLabel id="labelNameId" for="nameId" value="First Name" />
      <h:inputText id="nameId" required="true" value="#{dataBean.name}" />
      <h:message id="msgNameId" for="nameId"/>

      <o:outputLabel id="labelSurnameId" for="surnameId" value="Last Name" />
      <h:inputText id="surnameId" required="true" value="#{dataBean.surname}" />
      <h:message id="msgSurnameId" for="surnameId"/> 
                              
      <h:commandButton value="Register">
       <f:ajax execute="@form" render="@form" />
      </h:commandButton>
    </h:panelGrid>          
  </h:form>       
      
 </h:body>
</html>

So, OmniFaces passes the instance of the OutputLabel ("given component ") and the nameId ("given client ID "), which is the value of the for attribute, but, is also the clientId of the indicated component (the input text with this id).
The parent component that contains the " given client ID " is the form with id, registerFormId, NOT the output label with id labelNameId, or the panel grid with id, panelId.  This is happening because, the output label and the panel grid are not NamingContainers, so they don't pass this check!
In the figure below, you can see this use case - since the searched component is found by traversing the parents of the "given component ", there is no call of the findComponentInChildren() method:


A more comprehensive case can be like this (is just a re-write of the above example meant to force the call of the findComponentInChildren() method):

<?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 id="htmlId"  xmlns="http://www.w3.org/1999/xhtml"
      xmlns:o="http://omnifaces.org/ui"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:f="http://xmlns.jcp.org/jsf/core">
 <h:head id="headId">
   <title>Register Form</title>        
 </h:head>
 <h:body id="bodyId">

 <h:panelGrid id="panelId" columns="2">
  <o:outputLabel id="labelNameId" for=":registerFormNameId:nameId" value="First Name" />
  <o:outputLabel id="labelSurnameId" for=":registerFormSurnameId:surnameId" value="Last Name" />       

  <h:form id="registerFormNameId">
   <h:inputText id="nameId" required="true" value="#{dataBean.name}" />
   <h:message id="msgNameId" for="nameId"/>
   <h:commandButton value="Register Name">
    <f:ajax execute="@form" render="@form" />
   </h:commandButton> 
  </h:form>

  <h:form id="registerFormSurnameId">
   <h:inputText id="surnameId" required="true" value="#{dataBean.surname}" />
   <h:message id="msgSurnameId" for="surnameId"/>  
   <h:commandButton value="Register Surname">
    <f:ajax execute="@form" render="@form" />
   </h:commandButton> 
  </h:form>
 </h:panelGrid>    

 </h:body>
</html>

So, OmniFaces passes the instance of the OutputLabel ("given component ") and the :registerFormNameId:nameId ("given client ID "), which is the value of the for attribute, but, is also the clientId of the indicated component (the input text with this id). This time the findComponentInParents() reaches the UIViewRoot and will return true. This means that the findComponentInChildren() method enter in action. It will traverse, starting with the UIViewRoot, the component tree and will find the NamingContainer with id, registerFormNameId, as the component that contains the " given client ID". As you can see in the below figure, the findComponentInChildren() method traverse the component tree, including the nodes that already have been traversed by the findComponentInParents() - the checks, 8, 9 and 10. Obviously, calling the findComponentInParents() first is the best approach, since this methods jumps from parent to parent as a " kangaroo", while the findComponentInChildren() method involves a recursive process, which is by its nature less efficient.


You may find this dissertation useless, but many JSF developers uses the findXxx() methods, without understanding the process behind the scene. Once you understand how this process works, you can write your own findXxx() methods, optimize/adjust the existing ones to obtain more power, flexibility and performance in particular cases. There is no rational reason to ignore the time spent by the application to traverse/find components in component tree.
I hope that this dissertation revealed to you the OmniFaces, findComponentRelatively(),findComponentInParents() and findComponentInChildren() methods, and that you will find them useful in your projects. Moreover, they can inspire you to contribute with your own findXxx() methods.

JSF BOOKS COLLECTION

Postări populare

Visitors Starting 4 September 2015

Locations of Site Visitors