Thursday, June 14, 2012

The Different Ways To Specify the Converter and the Validator In JSF

When writing JSP pages in JSF, you can use different ways to specify the converter and/or the validator for an input. If the customer converter/validator does not need any parameters, then the task is easy. But if the customer converter/validator needs to take any parameter, the thing will be more involved.

The Customer Converter

The Customer Converter Without Parameters

In the following, we use the conventional prefix "f" and "h" for the JSF core and html tag libraries respectively. We also assume that there is a customer converter with the ID com.sample.customer.converter.id and the class name com.sample.CustomerConverter. Furthermore, we assume that this converter is used to do the conversion between a string and the object of the class com.sample.CustomerObject.
Method 1
Use the converter ID. The converter ID is declared in the faces-config.xml file.
<h:inputText value="#{someBean.someVar}">
  <f:converter converterId="com.sample.customer.converter.id"/>
</h:inputText>
Method 2
Use the converter attribute:
<h:inputText value="#{someBean.someVar}" converter="com.sample.customer.converter.id" />
Method 3
Implements a method in the back bean to return a converter:
   <h:inputText value="#{someBean.somevar}" converter="#{backBean.converter}" />
Here the backBean class must implement the following method:
  public Converter getConverter(){...}
Method 4
If the converter class CustomerConverter is used for all the conversions between the String and the object of the class CustomerObject, you can specify CustomerConverter as the default for the CustomerOjbect class in faces-config.xml. And that is it. No other things in JSP pages are needed.

In faces-config.xml, do the following:

    <converter>
       <converter-for-class>com.sample.CustomerObject</converter-for-class>
       <converter-class>com.sample.CustomerConverter</converter-class>
    </converter>
In the JSP file, you simply write
<h:inputText value="#{someBean.someVar}" />
Note that here the type of the variable someVar must be the class CustomerObject.

The Customer Converter With Parameters

In this case, you will need to implement the converter class and the tag handler class for the converter. The tag handler class should extend the JSF class ConverterELTag. It should have the method createConverter() that returns an instance of the converter class. You also need to create the customer TLD file for your tag classes.

Note that there is also a way so you can have a customer converter that needs parameters but you do not need to create the tag handler class and TLD files. You can just as simply use the methods described in the section "The Customer Converter Without Parameters". The trick is to pass the parameter to the back bean and get the value of that parameter from the bean when the customer converter does the conversion. The following is an example.

  <h:outputText value="#{someBean.someVar}">
     <f:converter converterId="myConverterId" />
     <f:attribute name="myConverterParameterName" value="someValue" />
  </h:outputText>
Then in the converter, you can get the parameter value as follows:
     parameterValue = component.getAttributes().get("myCoverterParameterName");


The Customer Validator

The Customer Validator Without Parameters

Mehtod 1
   <h:inputText .... >
      <f:validator validatorId="..." />
   </h:inputText>
Method 2
   <h:inputText value="#{someBean.someVar}" validator="#{someBean.validatingMethod}" />
Notice here that the method in the "validator" attribute does not return an object of the validator class. Instead, its return type is void. This is different from the converter case where the corresponding method returns an object of the customer converter class. Here the validation method validates the data and throws a ValidatorException( a Runtime exception ) if it finds any error.

The Customer Validator With Parameters

In this case, you will need to implement the validator class and the tag handler class for the validator. The tag handler class should extend the JSF class ValidatorELTag. It should have the method createValidator() that returns an instance of the validator class. You also need to create the customer TLD file for your tag classes.

References

1. Core JavaServer Faces by David Geary and Cay Horstmann

How to Specify Source Code When Debugging in Eclipse

You can have multiple application projects in Eclipse. You can use Eclipse to start a weblogic server in the debug mode. And then you can debug your web applications deployed to the weblogic server. You may want to debug into the source code of the libraries used in your application. For example, you may want to debug into the jsf-impl.jar. You may use different versions of jsf-impl in different applications. So how to use the source code that matches the library? It is actually easy. The following are the steps.
  1. In eclipse, go to "Run --> Debug configurations...". This will open the configuration screen.
  2. In the screen, the left pane shows a list of the programs. Click on the one you are using. In this example, it is "Oracle Weblogic Server 11gR1 PatchSet 1 at localhost".The right pane will show tabs named "Server", "Source", "Environment", etc.
  3. In that right pane, click on the "Source" tab. You will see a list of the projects and files. These are the source code files that eclipse uses to show in debugging.
  4. In that right pane, you can use the "Add" button to add source code file. You can also have different versions of the source code for a library. In that case, you can use the "Up" and "Down" button to move the positions of the source code file. The one sitting higher will be picked up.

Wednesday, June 13, 2012

JSF and JSP Architecture Models

There are two models for building applications using the JSP and servlet technology.

The Model 1 Architecture

In this model, the target of every request is a JSP page. The JSP page does all the things to answer the request. It can use JavaBeans to access database or other services.

The Model 2 Architecture

This model follows the Model-View-Controller(MVC) design pattern. In this architecture, all the requests are received by the servlets first. The servlets act as the controller. They analyze the request, get the data into JavaBeans, and finally dispatch the requests to JSP pages. The JavaBeans act as the model. And the JSP pages act as the view.

What about JSF?

We know every JSP page is actually a servet. It will be compiled to a servlet class by the web container. Now in the JSF world, with all those JSF lifecyle phases, is it still following the Model 2 architecture? The answer is still "Yes" because the JSP file gives the layout and appearance of the page. But unlike the old jsp/servlet technology where the JSP writes out all the HTML text, in JSF, the servlet generated from the JSP page only produces some simple HTML text such as the header("Content-type", "text/html"). Mostly it just processes the tags and creates the object tree into the Context which are used to build the JSF component tree. Later on the faces servlet gets the component tree from the context and spits out the actual HTML text in the renderers of the components in the component tree.

Roughly speaking, in the traditional Model 2, the servlet does not do much. basically it just dispatches the requests to the JSP pages and its job is done. But in JSF, the servlet will execute the JSF life cycle for every request. At some point in the life cycle, the servlet will dispatch the request to the JSP. The JSP will do its job and save the the work into the conetxt. Then the execution will return to the servlet for the life cycle to finish.

The following is one actual stacktrace from a sample JSF application. It shows an error. But that is not the interest here. From the stacktrace, we can see how the whole thing works together. We can see the following:

  1. The faces servlet acts as the controller. The JSF lifecyle is executed in the controller.
  2. The splitting line in the stacktrace is the one containing the following: com.sun.faces.context.ExternalContextImpl.dispatch. This is where the faces servlet dispatches the request to the JSP page.
  3. After the faces servlet dispatches the request, the servlet generated by the JSP will take over the task. In the example, it is jsp_servlet.__index.class which is generated from the JSP page index.jsp. It is missing in this case. So an error occurs.
  4. The jsp_servlet processes the tags in the JSP page, creates the corresponding objects from the tags and stores them into the pageContext. The jsp_servlet does not write out the actual HTML text from the tags.
  5. Later on in the JSF lifecycle, the JSF renderers will write out the actual HTML text that will be sent to the browser. And these occurs in the faces servlet.
javax.servlet.ServletException: [HTTP:101249][ServletContext@11930454[app:spinner module:spinner path:/spinner spec-version:2.5]]: Servlet class jsp_servlet.__index for servlet /index.jsp could not be loaded because the requested class was not found in the classpath .
java.lang.ClassNotFoundException: jsp_servlet.__index.
 at weblogic.servlet.internal.ServletStubImpl.prepareServlet(ServletStubImpl.java:543)
 at weblogic.servlet.jsp.JspStub.prepareServlet(JspStub.java:271)
 at weblogic.servlet.jsp.JspStub.prepareServlet(JspStub.java:191)
 at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:235)
 at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:175)
 at weblogic.servlet.internal.RequestDispatcherImpl.invokeServlet(RequestDispatcherImpl.java:502)
 at weblogic.servlet.internal.RequestDispatcherImpl.forward(RequestDispatcherImpl.java:248)
 at  com.sun.faces.context.ExternalContextImpl.dispatch(ExternalContextImpl.java:410)
 at com.sun.faces.application.ViewHandlerImpl.executePageToBuildView(ViewHandlerImpl.java:469)
 at com.sun.faces.application.ViewHandlerImpl.renderView(ViewHandlerImpl.java:140)
 at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:110)
 at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:100)
 at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
 at javax.faces.webapp.FacesServlet.service(FacesServlet.java:245)
 at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:227)
 at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:125)
 at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:292)
 at weblogic.servlet.internal.TailFilter.doFilter(TailFilter.java:26)
 at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)
 at weblogic.servlet.internal.RequestEventsFilter.doFilter(RequestEventsFilter.java:27)
 at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)
 at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3592)
 at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
 at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:121)
 at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2202)
 at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2108)
 at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1432)
 at weblogic.work.ExecuteThread.execute(ExecuteThread.java:201)
 at weblogic.work.ExecuteThread.run(ExecuteThread.java:173)
In the correct version for the example above, the class jsp_servlet._index.class is at the right location. Looking at the actual code, you can see the majority of the class is the methods of the following type:
private boolean _jsp__tagX(javax.servlet.ServletRequest request, javax.servlet.ServletResponse response, javax.servlet.jsp.PageContext pageContext, javax.servlet.jsp.tagext.JspTag activeTag, com.sun.faces.taglib.html_basic.PanelGridTag parent) throws java.lang.Throwable
    {
The method name is _jsp__tagX, where 'X' is a number. For this particular example, there are 12 such methods. X is from 0 to 11, each corresponding to an actual tag in the JSP file.

A main method in _index.java is the following:

public final class __index extends  weblogic.servlet.jsp.JspBase  implements weblogic.servlet.jsp.StaleIndicator {
...
    public void _jspService(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) 
    throws javax.servlet.ServletException, java.io.IOException {

        javax.servlet.ServletConfig config = getServletConfig();
        javax.servlet.ServletContext application = config.getServletContext();
        javax.servlet.jsp.tagext.JspTag _activeTag = null;
        java.lang.Object page = this;
        javax.servlet.jsp.PageContext pageContext = javax.servlet.jsp.JspFactory.getDefaultFactory().getPageContext(this, request, response, null, true , 8192 , true );
        response.setHeader("Content-Type", "text/html");
        javax.servlet.jsp.JspWriter out = pageContext.getOut();
        weblogic.servlet.jsp.ByteWriter bw = (weblogic.servlet.jsp.ByteWriter)out;
        bw.setInitCharacterEncoding(_WL_ORIGINAL_ENCODING, _WL_ENCODED_BYTES_OK);
        javax.servlet.jsp.JspWriter _originalOut = out;
        javax.servlet.http.HttpSession session = request.getSession( true );
        try {;
            bw.write(_wl_block0Bytes, _wl_block0);
            bw.write(_wl_block1Bytes, _wl_block1);
            bw.write(_wl_block1Bytes, _wl_block1);
            bw.write(_wl_block1Bytes, _wl_block1);

            if (_jsp__tag0(request, response, pageContext, _activeTag, null))
             return;
            bw.write(_wl_block9Bytes, _wl_block9);
        } catch (java.lang.Throwable __ee){
            if(!(__ee instanceof javax.servlet.jsp.SkipPageException)) {
                while ((out != null) && (out != _originalOut)) out = pageContext.popBody(); 
                _releaseTags(pageContext, _activeTag);
                pageContext.handlePageException(__ee);
            }
        }
    }
....

}
The method above calls _jsp_tag0() which will in turn calls _jsp_tag1(), .... The mehtod _jsp_tag0 is for the ViewTag. The method is as follows:
 private boolean _jsp__tag0(javax.servlet.ServletRequest request, javax.servlet.ServletResponse response, javax.servlet.jsp.PageContext pageContext, javax.servlet.jsp.tagext.JspTag activeTag, javax.servlet.jsp.tagext.JspTag parent) throws java.lang.Throwable
    {
        javax.servlet.jsp.tagext.JspTag _activeTag = activeTag;
        javax.servlet.jsp.JspWriter out = pageContext.getOut();
        weblogic.servlet.jsp.ByteWriter bw = (weblogic.servlet.jsp.ByteWriter) out;
         com.sun.faces.taglib.jsf_core.ViewTag __tag0 = null ;
        int __result__tag0 = 0 ;

        if (__tag0 == null ){
            __tag0 = new  com.sun.faces.taglib.jsf_core.ViewTag ();
            weblogic.servlet.jsp.DependencyInjectionHelper.inject(pageContext, __tag0);
        }
        __tag0.setPageContext(pageContext);
        __tag0.setParent(null);
        __tag0.setJspId("id0");
        _activeTag=__tag0;
        __result__tag0 = __tag0.doStartTag();

        if (__result__tag0!= javax.servlet.jsp.tagext.Tag.SKIP_BODY){
            try {
                if (__result__tag0== javax.servlet.jsp.tagext.BodyTag.EVAL_BODY_BUFFERED) {
                    out = pageContext.pushBody();
                    bw = (weblogic.servlet.jsp.ByteWriter)out;
                    __tag0.setBodyContent(( javax.servlet.jsp.tagext.BodyContent)out);
                    __tag0.doInitBody();
                }
                do {
                    bw.write(_wl_block2Bytes, _wl_block2);

                    if (_jsp__tag1(request, response, pageContext, _activeTag, __tag0))
                     return true;
                    bw.write(_wl_block3Bytes, _wl_block3);

                    if (_jsp__tag2(request, response, pageContext, _activeTag, __tag0))
                     return true;
                    bw.write(_wl_block8Bytes, _wl_block8);
                } while (__tag0.doAfterBody()== javax.servlet.jsp.tagext.IterationTag.EVAL_BODY_AGAIN);
            } finally {
                if (__result__tag0== javax.servlet.jsp.tagext.BodyTag.EVAL_BODY_BUFFERED) {
                    out = pageContext.popBody();
                    bw = (weblogic.servlet.jsp.ByteWriter)out;
                }
            }
        }
        if (__tag0.doEndTag()== javax.servlet.jsp.tagext.Tag.SKIP_PAGE){
            _activeTag = null;
            _releaseTags(pageContext, __tag0);
            return true;
        }
        _activeTag=__tag0.getParent();
        weblogic.servlet.jsp.DependencyInjectionHelper.preDestroy(pageContext, __tag0);
        __tag0.release();
        return false;
    }

Notice that line in red "weblogic.servlet.jsp.DependencyInjectionHelper.inject(pageContext, __tag0);". This looks like to process the tag and save the values into the pageContext. The other methods _jsp_tagX() are similar.

Understanding the Java Stack Trace

The java stacktrace often contains something like "... 10 more Caused by". What does the number in this string mean? The following is the javadoc of the class Throwable. It has a good explanation. It can be found online at http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Throwable.html.

pringStackTrace

public void printStackTrace()
Prints this throwable and its backtrace to the standard error stream. This method prints a stack trace for this Throwable object on the error output stream that is the value of the field System.err. The first line of output contains the result of the toString() method for this object. Remaining lines represent data previously recorded by the method fillInStackTrace(). The format of this information depends on the implementation, but the following example may be regarded as typical:
 java.lang.NullPointerException
         at MyClass.mash(MyClass.java:9)
         at MyClass.crunch(MyClass.java:6)
         at MyClass.main(MyClass.java:3)
This example was produced by running the program:
 class MyClass {
     public static void main(String[] args) {
         crunch(null);
     }
     static void crunch(int[] a) {
         mash(a);
     }
     static void mash(int[] b) {
         System.out.println(b[0]);
     }
 }
The backtrace for a throwable with an initialized, non-null cause should generally include the backtrace for the cause. The format of this information depends on the implementation, but the following example may be regarded as typical:
 HighLevelException: MidLevelException: LowLevelException
         at Junk.a(Junk.java:13)
         at Junk.main(Junk.java:4)
 Caused by: MidLevelException: LowLevelException
         at Junk.c(Junk.java:23)
         at Junk.b(Junk.java:17)
         at Junk.a(Junk.java:11)
         ... 1 more
 Caused by: LowLevelException
         at Junk.e(Junk.java:30)
         at Junk.d(Junk.java:27)
         at Junk.c(Junk.java:21)
         ... 3 more
Note the presence of lines containing the characters "...". These lines indicate that the remainder of the stack trace for this exception matches the indicated number of frames from the bottom of the stack trace of the exception that was caused by this exception (the "enclosing" exception). This shorthand can greatly reduce the length of the output in the common case where a wrapped exception is thrown from same method as the "causative exception" is caught. The above example was produced by running the program:
 public class Junk {
     public static void main(String args[]) { 
         try {
             a();
         } catch(HighLevelException e) {
             e.printStackTrace();
         }
     }
     static void a() throws HighLevelException {
         try {
             b();
         } catch(MidLevelException e) {
             throw new HighLevelException(e);
         }
     }
     static void b() throws MidLevelException {
         c();
     }   
     static void c() throws MidLevelException {
         try {
             d();
         } catch(LowLevelException e) {
             throw new MidLevelException(e);
         }
     }
     static void d() throws LowLevelException { 
        e();
     }
     static void e() throws LowLevelException {
         throw new LowLevelException();
     }
 }

 class HighLevelException extends Exception {
     HighLevelException(Throwable cause) { super(cause); }
 }

 class MidLevelException extends Exception {
     MidLevelException(Throwable cause)  { super(cause); }
 }
 
 class LowLevelException extends Exception {
 }
But be careful about the accuracy here. The following is also from the javadoc about the method
public StackTraceElement[] getStackTrace()
Provides programmatic access to the stack trace information printed by printStackTrace().

Some virtual machines may, under some circumstances, omit one or more stack frames from the stack trace. In the extreme case, a virtual machine that has no stack trace information concerning this throwable is permitted to return a zero-length array from this method. Generally speaking, the array returned by this method will contain one element for every frame that would be printed by printStackTrace.

Reference

1. http://stackoverflow.com/questions/1043378/print-full-call-stack-on-printstacktrace

Tuesday, June 12, 2012

How is a converter wired to a JSF tag?

The following is a piece of sample code in JSF that uses converter:
 <h:inputText id="date" value="#{payment.date}"> 
      <f:convertDateTime pattern="MM/yyyy"/>
 </h:inputText>
The convertDateTime converter is an independent object from the inputText tag handler class. Then how does the inputText tag know to use the convertDateTime converter to process the date value? The secret is in the component class. We know the tag handler class has an API method
   public String getComponentType() {...}
 
that tells its component class. The component class has an API method
   public String getRenderType(){...}
 
that tells the renderer class. The renderer class has the API method
   public Object getConvertedValue(FacesContext context,
                                       UIComponent  component,
                                    Object       submittedValue)
   {...}
 
that converts the value. So it is the responsibility of the renderer class to convert the value. For example, the standard component class UIInput uses the specified converter. If you need to create a customer renderer, you will need to set the converter in the renderer.

Monday, June 11, 2012

How Are the JSF Tags Processed In The JSF Lifecycle

When the browser first connects to a jsp page, JSF will execute two phases Restore_View and Render_Response. It creates the view in the Restoer_View phase. But here it is just an empty ViewRoot and it is put into the facescontext. In the Render_Response phase, JSF will creates the actual UI components and build the view. It will also save the view into the session using the class com.sun.faces.application.StateManagerImpl. Here is what happens in the Render_Response phase.

(A) It calls ViewHandlerImpl.executePageToBuildView(...)

  1. The servlet reads the page.
  2. The page contains JSF tags. Each tag has an associated tag handler class. As tags are read, the tag handler classes are executed.
  3. The tag handlers collaborate with each other to build a component tree.
Now let's see some more details in step 2. How are those tag handler classes identified and retrieved? A jsp page declares the tag libraries it used in the beginning of the page. It may use one of the following two formats:
  • <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
  • <jsp:root xmlns:h="http://java.sun.com/jsf/html">
The uri value is used as the identifier by the servlet to locate the TLD file. The TLD file defines its uri value inside itself. The servlet will search for the TLD files at the standard locations to find the matching TLD file.

The TLD file also declares the class name for the tag. That is the tag handler to be invoked. The servlet can just use to class name to load the class.

The tag handler has an instance field for each attribute and the corresponding setter method. When the tag is processed, each tag attribute value is converted to a ValueExpression object, and the setter method is called.

The tag handler also knows the corresponding component class. It has the following method:

public String getComponentType(){...}
The implementation of the tag handler class returns a type value. However this type value is not necessarily the classname of the component class. It is used as an ID to find the class name in the faces-config.xml file. An example is as follows:
<component>
  <component-type>
     com.foo.Xyz
  </component-type>
  <component-class>
     com.foo.UIXyz
  </component-class>
</component>
The tag handler class uses the setProperties(UIComponent component) method to save the attribute values into the component class.

Note: A tag handler may not have a component class. For example, the <f:view> tag has the tag handler class com.sun.faces.taglib.jsf_core.ViewTag. Its getComponentType() method is as follows:

 /**
     * This should never get called for PageTag.
     */
 public String getComponentType() {
        assert (false);
        throw new IllegalStateException();
    }
The javadoc of this class says the following:
/**
 * All JSF component tags must be nested within a f:view tag.  This tag
 * corresponds to the root of the UIComponent tree.  It does not have a
 * Renderer. It exists mainly to provide a guarantee that all faces
 * components reside inside of this tag.
 */

The JSF tags implement the JSP Tag interface. So basically this is the JSP technology. What is different in JSF is that many of the JSF tags have associated component class. And these component classes are put together to form a component tree, which is a center piece in JSF technology.

In the JSP technology, a JSP tag can also have attributes. The tag implementation also needs the setter method for each of the attributes. When the JSP engine encounters the attributes in the tag, it calls the setter methods. Then when the doStartTag() method or other methods of the Tag interface is called, it can print out the attribute value or do anything related to the attribute. In JSF, there are also the setter methods for the attributes. But the tag handler has a new method setProperties(), where the attributes are saved to the component class of the tag.

So compared to the JSP technology, the basic strategy of JSF seems to be that instead of processing the tags and the attributes immediately, it temporarily saves the attribute values into the component tree, and then processes these values in different phases in the JSF lifecycle.

All the above happens in step (A). Now the next step is step (B).

(B) It calls ViewHandlerImpl.renderView(....) to render the page

In this step, all text in the JSP file that is not a JSF tag is passed through. The component classes execute the following render mehtods to produce the HTML text:

  1. encodeBegin()
  2. encodeChildren()
  3. encodeEnd()
These methods basically print out the HTML text.They use the attributes that the tag handlers have saved into them in step (A).

Next the encoded page is sent to the browser.

The browser displays the page. The user fills in the form fields and submits the page.

The JSF framework calls the RestoreView phase and then the ApplyRequestValues phase.

In the ApplyRequestValues phase, the decode() method of the component classes are executed. What does the decode() method do? The method will use the FacesContext to get the request parameter, process it, and calls the method setSubmittedValue(Object). This method is inherited from the class javax.faces.component.UIInput. Notice that this method takes only one parameter. So it seems that an UIInput tag can only deal with one value.

So the submitted value is stored in the component regardless if it is valid or not. But the decode() method will set a flag if it is valid. Subsequently in the JSF life cycle, the value will be converted and validated by the JSF framework.

The component class sets the converter for itself. It can also set its renderer.

References

1. Core JavaServer Faces second edition
2. http://java.sun.com/javaee/javaserverfaces/reference/docs/customRenderKit.html