Monday, September 17, 2012

Blog Three Year Anniversary

I just checked the date. Today is September 17, 2012. This blog site was created on September 12, 2009. So I just passed the three year anniversary by 5 days. Time flies ! The weather is good. Last week it was around 80F with little rain in Pittsburgh. Leaves have turned yellow or red a bit. This week it is getting a little cool. The temperature is around 70F.

Thursday, July 26, 2012

Various Ways for Navigation in JSF 2(draft)

The example is taken from the Icefaces 3 turorial http://wiki.icesoft.org/display/ICE/Getting+Started+with+ICEfaces+3 The file job-applicant.xhtml uses several navigation mechanisms.
  • Use the following:
     <h: button outcome="xyz" .../>
    The web will go directly xyz.xhtml. The URL in the browser is changed to something like ***/xyz.jsf
  • Use the following:
    <h:commandButton action="xyz" ... />
    Go to faces-config.xml to look for the <from-outcome> match for this page. The value in the <to-view-id> tag will be used and the the URL will be changed accordingly.
  • Use the following:
    <h:commandButton action="#{bean.method}" ... />
    Invoke the method of the bean. The return value is a string.
    1. The returned result is the following "abc?faces-redirect=true". In this case, the web will go to abc.xhtml. The URL is changed.
    2. The returned result is the following "abc". In this case, the web will show the content of abc.xhtml. But the URL will not change. So if the current page is xyz.xhtml, the new URL will still be xyz.xhtml instead of abc.xhtml.
    Note that this case of using bean method for the 'action' attribute in h:commandButton is syntactically the same as the case of using string literal for the 'action' attribute in h:commandButton. So maybe the navigation rule is the same. The navigation will first look for the match in faces-config.xml. If a match is not found, then it will just use the value of the 'action' attribute as the page name. It will either redirect to it or forward to it depending on the redirect flag.
  • <h:commandButton listener="#{bean.method}" ... />
    or
    <h:commandButton actionListener="#{bean.method}" ... />
    In these cases, the method returns void. So by default, the page submits to itself. The URL does not change.

Friday, July 13, 2012

Servet, JSF, Weblogic Standards Compliance

The question is can JSF 2 be used in weblogic 10?

The current version of JSF is 2. I think JSF is a layer on top of servlet. So between JSF and the application server, the common ground is the servlet version used. According to this link "http://javaserverfaces.java.net/presentations/20090520-jsf2-datasheet.pdf", JSF 2.0 is compatible with JavaEE 5 application servers, or any server implementing Servlet 2.5. For weblogic 10.3, it has a list of supported standards. From the link "http://docs.oracle.com/cd/E12840_01/wls/docs103/notes/new.html", it supports Java EE version 5.0 and Java EE servlet version 2.5, 2.4, 2.3, and 2.2. So here the common ground is servlet version 2.5, and it should be OK to use JSF 2 in weblogic 10.3.

The following information from wikipedia http://en.wikipedia.org/wiki/Oracle_WebLogic_Server is also helpful.

The table below lists major standards supported by WebLogic Server product version.

Standard WLS 7.0 WLS 8.1 WLS 9.0 WLS 10.0 WLS 10.3 WLS 12c
Java 1.3 1.4 5 5 6 (7 in 10.3.6+) 7
Java EE 1.3 1.3 1.4 5 5 6
Servlet 1.2 2.3 2.4 2.5 2.5 3.0
JSP 1.2 1.2 2.0 2.1 2.1 2.2
EJB 2.0 2.0 2.1 3.0 3.0 3.1
JDBC 2.0 2.0 3.0 3.0 3.0 4.0

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