Tuesday, July 27, 2010

Slow ICEFaces

ICEfaces (http://www.icefaces.org) is a great JSF framework. I recently developed an application using ICEfaces. On my development machine, everything worked well. However, when I deployed the application to our Linux test server, the whole application became very slow (I'm talking about 20 seconds per request).
After profiling the application, I found out that ICEfaces wraps each HttpServletRequest object to have a uniform interface over all the different Servlet specification versions. It caches some of the values from the HttpServletRequest, and there lies the culprit: one of the values it caches is the getLocalName() value. How this method is implemented depends on your Servlet container, but on apache it results in a call to InetAddress.getHostName(). InetAddress.getHostName() will perform a reverse DNS lookup on its IP address. And there lies the problem: our test server doesn't have a DNS entry, so this method fails (after trying for a very long time). Java will also not cache failed DNS lookup values (you can enable this, see http://download.oracle.com/docs/cd/E17476_01/javase/1.5.0/docs/guide/net/properties.html, but I wouldn't recommend doing so).

So there are 2 possible solutions:
  1. Add a DNS entry for your server (either in your DNS server or in the etc/hosts file or similar)
  2. Sometimes modifying the DNS is not possible (for any number of reasons). Another solution would be to create a Filter that overrides the default behavior of HttpServletRequest.getLocalName(). Here's an example:

public class LocalNameFilter implements Filter {

public void destroy() {
}

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest hsr = (HttpServletRequest) request;  
ServletRequestWrapper wrapper = new HttpServletRequestWrapper(hsr) {
@Override
public String getLocalName() {    
return "myHost";
}
};
chain.doFilter(wrapper, response);
}

public void init(FilterConfig fConfig) throws ServletException {
}

}

Don' forget to declare this filter in your web.xml:
<filter>  
<display-name>LocalNameFilter</display-name>
<filter-name>LocalNameFilter</filter-name>
<filter-class>com.xxx.web.LocalNameFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>LocalNameFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

No comments:

Post a Comment