Thursday 23 May 2013

Calling methods from Constructors, a definitive explanation by Dr Heinz M. Kabutz

I am a huge fan of Dr. Kabutz and have been following his Java Specialists newsletter for many years.

In the latest issue he explains and demonstrates the pitfalls of calling methods from within constructors.

Now I have always been a proponent of "don't put logic other than simple initialisation in constructors", in fact I have always introduced this as a "Golden Rule" when helping other developers.
I knew about most of the things that Dr. Kabutz explains here but never really found the time to really get into it and write things down. Now that Dr. Kabutz has done so I don't need to.

The majority of my work involves JSF/CDI/EJB/JPA. I still see many code examples which places significant code in the constructors of CDI Beans even from sources that claim to know better.
If you are in the habit of doing so you really need to read the newsletter and get into the habit of using @PostConstruct annotations in your code as well as adding lazy loading/evaluation to setter/getter methods.

Tuesday 14 May 2013

JSF Beginners Tips #1: request parameter encoding and date/times

As a habitual visitor to the PrimeFaces Forums I and other expert members often have to answer questions related to problems related to request parameter encoding and date/times.

Without further rambling from me an example of the first problem.


Typically a web application will use UTF-8 encoding for pages, requests and responses. Unfortunately this can lead to unexpected problems as illustrated by the following observations.

The poster had discovered that a JSF page which uses PrimeFaces for a partial submit will submit request parameters as expected

However when the same page used a non-AJAX request (full form post submit) the same parameters become garbled.
I was able to reproduce this behaviour with a simple form like this

<?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 xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:tst="http://java.sun.com/jsf/composite/composites"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:p="http://primefaces.org/ui">
    <f:view contentType="text/html" encoding="UTF-8">
        <h:head>
            <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
            <title>Facelet Title</title>
        </h:head>
        <h:body>
            <h:form>
                <tst:buttonFacet labelText="Press me!">
                    <f:facet name="commandButton">
                        <p:commandButton ajax="false" value="Waiting to be pressed!"/>
                    </f:facet>
                </tst:buttonFacet>
                <p>
                    <h:panelGroup>
                        <p:inputText id="myInput" value="#{inputCapture.input}" required="true" requiredMessage="Required">
                            <p:ajax event="blur" listener="#{inputCapture.inputListener()}" update="myMsg"/>
                        </p:inputText>
                        <p:messages id="myMsg" globalOnly="false"/>
                    </h:panelGroup>
                </p>
            </h:form>
        </h:body>
    </f:view>
</html>

The composite component and backing bean don't actually play a role in this, I used an existing page to see if I could reproduce the posters findings and was successful. Starting with the failure case any "special" characters like Ö and ü were recieved in a garbled state and by the look of things they were being decoded as if they were ISO-8859-1 when they are actually UTF-8.
Ajaxifying the p:commandButton results in a partial submit with the values not being incorrectly decoded.
Using Glassfish I observed the following being logged.

WARNING: PWC4011: Unable to set request character encoding to utf-8 from context /XXX, because request parameters have already been read, or ServletRequest.getReader() has already been called
An old friend indeed.
Glassfish is expected to behave as the spec says and in this case it actually does. If a form POST does not specify an encoding it is assumed that the request is encoded using ISO-8859-1 and decodes request parameters accordingly.
To correct this for Glassfish simply add a glassfish-web.xml with the following contents

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE glassfish-web-app PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Servlet 3.0//EN" "http://glassfish.org/dtds/glassfish-web-app_3_0-1.dtd">
<glassfish-web-app error-url="">
  <class-loader delegate="true"/>
  <jsp-config>
    <property name="keepgenerated" value="true">
      <description>Keep a copy of the generated servlet class' java code.</description>
    </property>
  </jsp-config>
  <parameter-encoding default-charset="UTF-8"/>
</glassfish-web-app>

Other servers will have other ways of fixing this, Tomcat for instance.
For a more in-depth explanation of this try here courtesy of Omnifaces.org.

Problem #2


Dates causes chaos! Simply adding a calender type widget or even a simple h:outputText where the output is a Date will often result in the date being displayed with a different, unexpected, value where often the time is out by an hour or even the date being out by a day or more. The actual value is still correct however.
This infuriating behaviour has probably caused quite a lot of premature balding in devs over the years however a simple fix is available.
Add the following to your web.xml.
<context-param>
        <param-name>javax.faces.DATETIMECONVERTER_DEFAULT_TIMEZONE_IS_SYSTEM_TIMEZONE</param-name>
        <param-value>true</param-value>
    </context-param>

At least this means that all the other date problems you have are less likely to be caused by the JSF container.

For a more complete explanation of why this is so try here.