Archive for category Java

The selfRendered attribute

This is an interesting problem related to the RichFaces rich:suggestionbox tag.

Let’s take the following code:

<rich:suggestionbox for="q" minChars="1"
    suggestionAction="#{myBean.mySuggestionAction}" var="result"
    limitToList="true">
    <h:column>
        <h:outputText value="#{result}" />
    </h:column>
</rich:suggestionbox>

If you use the code above as it is, the whole page is going to be processed each time the suggestionAction is called. And because the minChars attribute is set to 1, the action is going to be called each time the user enters a character! :-o
For obvious reason, such as performance issue, this is not ideal.

To avoid this behaviour, you simply need to set the attribute selfRendered to true as shown below:

<rich:suggestionbox for="q" minChars="1"
    suggestionAction="#{myBean.mySuggestionAction}" var="result"
    limitToList="true" selfRendered="true">
    <h:column>
        <h:outputText value="#{result}" />
    </h:column>
</rich:suggestionbox>

Here is the description of the selfRendered attribute from RichFaces documentation:

If “true”, forces active Ajax region render response directly from stored components tree, bypasses page processing. Can be used for increase performance. Also, must be set to ‘true’ inside iteration components, such as dataTable.

Don’t hesitate to add this attribute to increase the performance of your website. ;)

, , ,

No Comments

loadBundle’s behaviour with JSTL tags

Let’s start with a bit of knowledge.
f:loadBundle is a JSF tag which loads a resource bundle and saves it as a variable in the request scope. The RichFaces a4j:loadBundle tag is a substitution for the f:loadBundle tag and allows to use reference to bundle messages during the Ajax re-rendering.

When I discovered the RichFaces tag, I immediately replaced all the f:loadBundle tags by a4j:loadBundle. Was I right? I thought at first, but then I got a problem. :(

The problem was appearing when I started mixing RichFaces and JSF tags.
For example, let’s take the following resource bundle:

active=true

And the following code:

<a4j:loadBundle basename="Messages" var="msg" />
Active is #{msg.active} --
<c:if test="#{msg.active}">
	Hello World!
</c:if>

This displays ‘Active is true --‘.
What is wrong there? The active message is true but the c:if condition failed! 8-O

Let’s now try the following:

<a4j:loadBundle basename="Messages" var="msg" />
Active is #{msg.active} --
<c:if test="#{empty msg.active}">
	Hello World!
</c:if>

This displays ‘Active is true -- Hello World!‘.
What does that mean? It seems that JSTL doesn’t get the value of the active message but gets an empty string instead!

In conclusion, if the resource bundle is loading using the RichFaces tag, the messages will be not visible by the JSTL tags.
To fix this problem, you will have to also load the resource bundle using the JSF tag:

<a4j:loadBundle basename="Messages" var="msg" />
<f:loadBundle basename="Messages" var="msg" />
Active is #{msg.active} --
<c:if test="#{msg.active}">
	Hello World!
</c:if>

As expected, this displays ‘Active is true -- Hello World!‘. :)

, , , ,

No Comments

Clock change affecting date display

This is a very particular problem which happens only during the summer and not even in all the countries ! :o
The problem is related to the Daylight Saving Time (DST), also called British Summer Time (BST):

Daylight saving time is the practice of temporarily advancing clocks so that afternoons have more daylight and mornings have less. Typically clocks are adjusted forward one hour near the start of spring and are adjusted backward in autumn.

Okay, so how do we display dates with JSF?
Let’s take this can’t-be-simpler bean:

public class MyBean {
	public Date getDate() {
		return new Date();
	}
}

And let’s insert the following code in a JSF page:

#{myBean.date}

The result is Fri Sep 17 20:03:14 BST 2010 (when I wrote this article).
If I check my clock, the date and time above are correct.
So far so good. :)

Let’s now use the h:outputText tag from JSF:

<h:outputText value="#{myBean.date}"/>

The result is Sep 17, 2010.
Alright, the date is correct but the time is not displayed…

Let’s use the f:convertDateTime tag to also display the time:

<h:outputText value="#{myBean.date}">
	<f:convertDateTime pattern="E MMM dd HH:mm:ss z yyyy" />
</h:outputText>

The result is Fri Sep 17 19:03:14 GMT 2010.
What can we see here? The time went one hour backward!
Why that? well, simply because the date is now displayed in GMT, instead of BST earlier.

So, this means that the h:outputText tag is displaying the date in GMT by default, which would be fine in winter but not in summer.
In order to fix this behaviour, you need to add the attribute timeZone to the f:convertDateTime tag such as:

<h:outputText value="#{myBean.date}">
	<f:convertDateTime pattern="E MMM dd HH:mm:ss z yyyy" timeZone="GB" />
</h:outputText>

Note that if you put BST instead of GB in the timeZone attribute, the time zone is going to be actually set to BDST which stands for Bangladesh Daylight Saving Time! :D

, , , , ,

No Comments

How to configure JSF to get the browser Back button working

Lately, I had a problem with one of my JSF applications which is using RichFaces.
The problem was happening when the user was hitting the browser Back button. Well, you would say that it is a usual problem in web development. But still, because we cannot disable the browser Back button, the web application needs to work fine if the user decides to click on it!

Anyway, let’s get back on topic. As I said, the problem occurred if the user was clicking on the Back button but the funniest thing is it was happening when he was clicking twice on it! Why did it work fine when clicking once but not twice? :o

The solution is quite simple actually.
It was coming from one of the options in MyFaces configuration: com.sun.faces.numberOfViewsInSession.
Here is a quick explanation of this option:

com.sun.faces.numberOfViewsInSession
Specifies the number of views that are stored in the session when Server-Side State Saving is used. If set to true while client-side state saving is being used, reduces the number of bytes sent to the client by compressing the state before it is encoded and written as a hidden field. The default for this parameter is 15.

So basically, JSF is storing each page previously viewed by the user in session. And, as you can see from the description above, JSF will stored a maximum of 15 pages by default. However, it was set to 1 in my application, which means only ONE page would be stored…
This was obviously the reason why the application was working fine if the user was clicking only once on the Back button but not twice! :D

For the same reason, you should also check the option org.apache.myfaces.NUMBER_OF_VIEWS_IN_SESSION which is default to 20:

org.apache.myfaces.NUMBER_OF_VIEWS_IN_SESSION
Defines the number of the latest views that are stored in session. This option is only applicable if the state saving method is set to server. The default for this parameter is 20.

For more information about JSF options, please have a look at the following page:
http://publib.boulder.ibm.com/infocenter/wasinfo/v7r0/index.jsp?topic=/com.ibm.websphere.express.doc/info/exp/ae/rweb_jsfengine.html

, , , ,

No Comments

The message tags of MyFaces and RichFaces

Working on an application using MyFaces and RichFaces, I had no choice but understand what is the difference between the message tag provided by Myfaces (h:message) and the message tag overridden by RichFaces (rich:message).

These tags allow to display information about the first FacesMessage that is assigned to the component referenced by the “for” attribute. The difference is that the RichFaces tag has some extra functionalities such as Ajax rendering, error markers and predefined css class names.
Have a look at the following page for more details: http://livedemo.exadel.com/richfaces-demo/richfaces/message.jsf

This is all nice and well but it is not the only difference. Indeed, the HTML code generated by both these frameworks will also be different!

First of all, let’s see how the tag <h:message styleClass="errormsg" for="element"/> will be transformed. If there is no message to display, nothing will be generated (which is a good behaviour). However, if a message is present, the tag will be replaced by the following HTML code:

<span class="errormsg">Required.</span>

So far, so good!

But now let’s check what code RichFaces is generating for the tag <rich:message styleClass="errormsg" for="element"/>.
The following is the code created if there is NO message to render:

<span class="rich-message errormsg" id="form:j_id255">
    <span class="rich-message-label"></span>
</span>

And here is the code which will replace the RichFaces tag if there is a message to display:

<span class="rich-message errormsg" id="form:j_id255">
    <span class="rich-message-label">Required.</span>
</span>

As you can see, the main difference is that RichFaces is wrapping the original span tag into another span tag. But, it is also generating some code even if there is no message to display! You would ask why is it doing that? The response is simple. The wrapper span element is necessary for RichFaces to Ajax-render the message tag if an error message has to be displayed for the targeting element.

So make sure you don’t put any padding or margin style in your custom CSS class which I called ‘errormsg’ in my example. Otherwise, you might have a gap when you were expecting nothing… (this happened to me) ;)

, , , , , ,

1 Comment

How to personalise the URLs with Faces Navigation?

This is an important question if you want to have search engine friendly URLs on your website!
But unfortunately, the solution is not straightforward with JavaServer Faces (JSF). :(

First of all, for security reason JSF doesn’t allow you to use the GET method for your forms. I didn’t really understand why but this is very (too) restrictive!
Can you imagine Google doing the same thing? We would have the same URL for every search terms http://www.google.co.uk/search instead of something like http://www.google.co.uk/search?hl=en&safe=off&esrch=FT1&q=test&meta=&aq=f&aqi=g10&aql=&oq=&gs_rfai=.
It wouldn’t be very easy to share a search page with a friend if Google was using the POST method. ;)

So the question is how to get around this JSF limitation?

Let’s take a look at how would look our faces-navigation.xml file for a search page:

<navigation-case>
    <from-action>#{searchBean.searchAction}</from-action>
    <from-outcome>success</from-outcome>
    <to-view-id>/search.xhtml</to-view-id>
    <redirect />
</navigation-case>

In this example, all the JSF elements calling the action searchBean.searchAction will be redirected to the search.xhtml page.
But, how are we going to get the search parameters into the URL?

Ideally, it would be great to be able to do something like the following:

<navigation-case>
    <from-action>#{searchBean.searchAction}</from-action>
    <from-outcome>success</from-outcome>
    <to-view-id>/search.xhtml?q=#{param.q}</to-view-id>
    <redirect />
</navigation-case>

This solution would allow us to inject EL expressions into the URL before the page is redirected to the destination page.
In order to do this, we need to create our own view handler and register it to our application. 8-)

The code below is the view handler class which also includes some comments:

package com.logikdev.gui.handler;

import javax.el.ExpressionFactory;
import javax.el.ValueExpression;
import javax.faces.application.ViewHandler;
import javax.faces.context.FacesContext;

import com.sun.facelets.FaceletViewHandler;

/**
 * Overrides the Facelet view handler to support EL expressions in URLs.
 * @author Stéphane Moreau
 */
public class DynamicViewHandler extends FaceletViewHandler {

	public DynamicViewHandler(ViewHandler parent) {
		super(parent);
	}

	/* (non-Javadoc)
	 * @see com.sun.facelets.FaceletViewHandler#getActionURL(javax.faces.context.FacesContext, java.lang.String)
	 */
	@Override
	public String getActionURL(FacesContext context, String viewId) {
		String queryString = null;

		// Replace the EL expressions in the URL
		ExpressionFactory expressionFactory = context.getApplication().getExpressionFactory();
		ValueExpression valueExpression = expressionFactory.createValueExpression(context.getELContext(), viewId, String.class);
		String result = (String) valueExpression.getValue(context.getELContext());

		// Separate the query string from the URL
		int dotIndex = result.lastIndexOf('.');
		int questionMarkIndex = result.indexOf('?');
		if (questionMarkIndex != -1) {
			queryString = result.substring(questionMarkIndex, dotIndex);
			viewId = result.substring(0, questionMarkIndex) + result.substring(dotIndex);
		}

		// Call the parent without the query string
		result = super.getActionURL(context, viewId);

		// Put back the query string at the end of the URL
		if (queryString != null) {
			result += queryString;
		}

		return result;
	}

}

And the following is the code to put in the faces-config.xml file in order to register the newly created view handler to the application:

<application>
	<variable-resolver>org.springframework.web.jsf.DelegatingVariableResolver</variable-resolver>
	<view-handler>com.logikdev.gui.handler.DynamicViewHandler</view-handler>
</application>

One last thing!
This view handler also has a limitation which I wasn’t able to fix. :( The file extension has to ALWAYS be placed at the end of the to-view-id URL! The view handler will then put it back before the question mark.
For example:

<navigation-case>
	<from-action>#{searchBean.searchAction}</from-action>
	<from-outcome>success</from-outcome>
	<!-- The extension has to be at the end -->
	<to-view-id>/search?q=#{param.q}.xhtml</to-view-id>
	<redirect />
</navigation-case>

If you perform a search on ‘jsf’ with the above navigation rule, the user will be redirected to the page /search.xhtml?q=jsf.

, , , , ,

2 Comments

limitToList attribute prevents flashing

If you have some elements (or even the whole page) that flash/twinkle using RichFaces, it probably means that these elements are AJAX-rendering. The question is by whom and how to fix it?

A lot of tags in RichFaces can AJAX-render elements such as:

<a4j:form>
    <a4j:jsFunction name="updateName" reRender="showname">
        <a4j:actionparam name="param1" assignTo="#{userBean.name}"  />
    </a4j:jsFunction>
</a4j:form>

On the above example, the JavaScript function updateName will AJAX-render the element which has the ID showname.

In some cases, you would have some elements that would AJAX-render without asking them to do so!
I still didn’t figure it out why. :( (if anybody has an idea, please don’t hesitate to tell me!)

But, I found a way to prevent this!
You simply can add the following attribute to your tag:

limitToList="true"

You even can add it to the tags that don’t have a reRender attribute.
For example:

<a4j:form>
    <a4j:poll id="poll" interval="1000" limitToList="true" />
</a4j:form>

, , , ,

No Comments

WritableFont doesn’t like to be static!

While using the tool JExcelAPI within my Java application to generate Excel spreadsheets, I got the following exception:

java.lang.ArrayIndexOutOfBoundsException: 5
	at jxl.biff.IndexMapping.getNewIndex(IndexMapping.java:68)
	at jxl.biff.FormattingRecords.rationalize(FormattingRecords.java:388)
	at jxl.write.biff.WritableWorkbookImpl.rationalize(WritableWorkbookImpl.java:988)
	at jxl.write.biff.WritableWorkbookImpl.write(WritableWorkbookImpl.java:692)
	...


It appears that this exception occurs only when you try to generate more than one Excel spreadsheet! How strange is that! 8-O
After a bit of investigation, it seems that the problem comes from the use of the static modifier with a jxl.write.WritableFont variable.

I unfortunately don’t have the time to check the JExcelAPI code source to understand the root cause.
So my advice would be: “if you get EXACTLY the same stack trace, simply delete any static modifier you used with the WritableFont variables”. :-)

, , , , ,

2 Comments

Deploy your app to the root context

This is an easy trick which I am sure most of you already know.

Let’s take a Java application called MyAddressBook. Its generated war file could be called myaddressbook.war.

By default, when you deploy this web application to Tomcat, the URL to access it will be http://localhost:8080/myaddressbook/. And if you point a domain name such as ‘addressbook.com’ to this server, the URL would be http://addressbook.com/myaddressbook/.

I don’t know for you but I don’t like to systematically have the subfolder ‘myaddressbook’ after my domain. But maybe I am too picky! ;)

The idea is to deploy our application in the Tomcat root context.
You have two ways of doing this:

  • Define a ROOT.xml file in your conf/Catalina/localhost folder, or;
  • Rename your war file to ROOT.war.

Note that the case is important, it has to be ROOT in UPPERCASE! :)

Once this is done, you will be able to call your application via the URL http://localhost:8080/
or http://addressbook.com/. Way better! 8-)

, ,

No Comments

How to monitor your Java application

It is very good to have your application and your database running on a Linux or Windows server, but who will tell you if your website is down? Who said “the users”? 8-O No, you won’t look very professional if you wait for a user complaint.

What you need to do is to monitor your server. But which tools to use? There are so many on the market… :(

I tested a few of them (Hyperic, Nagios, Zenoss, Cacti, Monitis) but the one I choose is Zabbix. What I like with Zabbix is its price (free 8-) ) and the fact that it is easy to configure and very flexible. Indeed, you can monitor anything you want on the machine (CPU, network, disk space, services, etc)! :)

However, if you also want to monitor your Tomcat application server or even Hibernate Java library, you need some more work.


To monitor Tomcat, you first need to enable JMX Remote. To do so, you can have a look at the official documentation or simply add the following parameters to your Tomcat startup script:

export CATALINA_OPTS='-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=8999 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false'


Then, I will recommend you to deploy Zapcat JMX Zabbix Bridge in your Tomcat web server. This tool has been developed to simplify the communication between the JMX management API inside Java applications and the Zabbix monitoring tool.

To read the installation instructions for Tomcat, please click on the following link:
http://www.kjkoster.org/zapcat/Tomcat_How_To.html


Finally, if you are using Hibernate in your Java application and would like to monitor it, you have to instantiate and configure a Hibernate MBean (org.jboss.hibernate.jmx.Hibernate) that will be responsible for constructing a Hibernate SessionFactory and exposing it to your application through JNDI.

Here are the lines you need to add to your context XML file:

<bean id="mbeanExporter" class="org.springframework.jmx.export.MBeanExporter" lazy-init="false">
    <property name="server" ref="mbeanServerFactory"/>
    <property name="beans">
        <map>
            <entry key="org.hibernate:type=statistics"  value-ref="hibernateMBean"/>
        </map>
    </property>
</bean>

<bean id="mbeanServerFactory" class="org.springframework.jmx.support.MBeanServerFactoryBean">
    <property name="locateExistingServerIfPossible" value="true"/>
</bean>

<bean id="hibernateMBean" class="org.hibernate.jmx.StatisticsService">
    <property name="sessionFactory" ref="sessionFactory"/>
    <property name="statisticsEnabled" value="true"/>
</bean>

, , , , , , ,

No Comments