Sleep

I always forget how to sleep or wait in Java though it’s quite easy, just use the static method Thread.sleep.

For example:

    // sleep the filter's wait interval
    try {
      Thread.sleep(filter.getWaitInterval() * 1000);
    }
    catch (InterruptedException exc) {
      logger.error("unexpected interrupt", exc);
    }

Sun has a tutorial calling Pausing Execution with Sleep.

Removing a Cookie

To remove a cookie the Java API suggests getting the cookie, setting its maxAge to 0, and then adding that cookie to the response.  Digging around deeper I realized you also need to set the domain and the path to match the cookie’s domain and path.  Here is an example of how to do this.

    Cookie [] cookies = request.getCookies();
    for (Cookie cookie : cookies) {
      if (cookie.getName().equals(COOKIE_WE_WANT)) {
        cookie.setMaxAge(0);
        cookie.setDomain(".betweengo.com");
        cookie.setPath("/");
        response.addCookie(cookie);
        break;
      }
    }

Note that if the domain was not set when the cookie was created then you should not set it when you try to remove it. Similarly with the path property. For example if the domain was not set at creation then the code would look like this:

    Cookie [] cookies = request.getCookies();
    for (Cookie cookie : cookies) {
      if (cookie.getName().equals(COOKIE_WE_WANT)) {
        cookie.setMaxAge(0);
        cookie.setPath("/");
        response.addCookie(cookie);
        break;
      }
    }

Also you should ensure that you add the cookie to the response before the response has already been committed.  Previously the above code was in a tag but that was too late to modify the response.  I moved this code to a filter and then it worked fine.

Finally you can do this in JavaScript. Doing it in JavaScript has the downside that it is done after the page is loaded. But it’s definitely helpful for testing. Here’s an example of deleting the cookie named “foo”.

document.cookie = 'foo=;expires='+new Date(0).toUTCString()+';';

In the above example I did not set the path or the domain. One will need to do that if the path and/or domain were set in the cookie at creation.

Unexplainable JSP Compilation Problem

I was getting a JSP compilation problem that I could not solve.

org.apache.jasper.JasperException: Unable to compile class for JSP
        at org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:510)
        at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:375)
        at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:314)
        at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:264)

org.apache.jasper.JasperException: Unable to compile class for JSP
        at org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:572)
        at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:303)

java.lang.NumberFormatException: For input string: "${status.index}"
        at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
        at java.lang.Integer.parseInt(Integer.java:447)
        at java.lang.Integer.valueOf(Integer.java:553)
        at org.apache.jasper.compiler.JspUtil.coerceToInt(JspUtil.java:752)
        at org.apache.jasper.compiler.Generator$GenerateVisitor.convertString(Generator.java:2949)

The major problem was this was happening on the server but not locally.  The compilation problem was occurring for this line.

<uportal:module definition="${module}" moduleIndex="${status.index}"/>

The moduleIndex value is “${status.index}”. Locally when the JSP compiler encounters this it knows to call my setter for moduleIndex that takes a String parameter. But on the server the JSP compiler seemed to insist on using the setter for moduleIndex that takes an integer parameter, hence the compilation problem.

I finally posted on the Sun Forums and with the help of evnafets I came up with two solutions.

  1. The correct solution is to upgrade my application to use JSTL 1.1.  Then the JSTL expressions such as “${status.index}” will be evaluated by the container.  Then I don’t have to have a setter that takes a String parameter, the JSTL expression, and evaluate it myself.  I can just use a setter that takes an integer parameter.
  2. The quick, hack solution which is to get rid of the setter that takes an integer parameter.  Wherever the application passes in an integer parameter, I change it to pass in a String representation of that integer.

Upgrading to JSTL 1.1

Based on this excellent post I came up with the following instructions for upgrading from JSTL 1.1.

  1. Update URI in JSP pages to use JSTL 1.1.
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
  2. Install in WEB-INF/lib the two JSTL 1.1 jars, standard.jar and jstl.jar.  You can get these from The Jakarta Site – Standard 1.1 Taglib Downloads.
  3. Update the start of web.xml to look like this.
    <?xml version="1.0" encoding="ISO-8859-1"?>
    <web-app xmlns="http://java.sun.com/xml/ns/j2ee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
        version="2.4">

Do Not Return From a Try Block

Practical Java(TM) Programming Language Guide (Addison-Wesley Professional Computing Series)In Peter Hagar’s book, Practical Java, he recommends that you do not return from a try block.  This is because the finally block may change the return value.

Traditionally, programmers think that when they execute a return statement they immediately leave the method they are executing.  In Java, this is no longer true with the usage of finally

To avoid this pitfall, be sure you do not issue a return, break or continue statement inside of a try block. If you cannot avoid this, be sure the existence of a finally does not change the return value of the method. This particular problem can arise during maintenance of your code, even with careful design and implementation. Good comments and careful code reviews ward it off.

Practical Java Programming Language … – Google Book Search

URL.equals and hashCode make blocking Internet connections

Who knew that something as innocent as java.net.URL.equals and hashCode would make blocking Internet connections?

The javadoc of URL.equals says: “Since hosts comparison requires name resolution, this operation is a blocking operation.”, but who reads the documentation of equals?  There is a general contract around equals.  Joshua Bloch writes in Effective Java: “Don’t write an equals that relies on unreliable resources” (Chapter 3, page 34). Hey Sun, as far as I know, the Internet is not reliable 😉

Eclipse and Java Blog by Michael Scharf: java.net.URL.equals and hashCode make (blocking) Internet connections….

ServletException root cause

Java’s Throwable class defines the getCause() method for accessing the cause of the exception.  This method returns a Throwable object which itself could have a cause.  By traversing down this chain you can find the root cause of an exception.

However for some unknown reason in ServletException the getRootCause() method was added.  Therefore when trying to determine the root cause of an exception in a J2EE environment one has to check what type of exception you have.  I do this in the following code.

  /**
   * Logs all the nested exceptions for the specified exception.
   *
   * @param ex the exception
   */
  protected void logNestedExceptions(Throwable ex) {
    int count = 1;
    Throwable cause = getCause(ex);
    while (cause != null) {
      logger.error("Nested Exception " + count, cause);
      cause = getCause(cause);
      count++;
    }
  }

  /**
   * Gets the cause of the exception.
   *
   * @param ex the exception
   * @return the cause
   */
  protected Throwable getCause(Throwable ex) {
    Throwable cause;
    if (ex instanceof ServletException) {
      ServletException sex = (ServletException) ex;
      cause = sex.getRootCause();
    }
    else {
      cause = ex.getCause();
    }
    return cause;
  }

Finally you need to configure web.xml to use your SiteMap servlet.

<servlet>
    <servlet-name>sitemap</servlet-name>
    <servlet-class>com.betweengo.servlet.SiteMap</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>sitemap</servlet-name>
    <url-pattern>/sitemap.xml</url-pattern>
</servlet-mapping>

Effective Java Collections

I thought this article, Effective Java Collections, was excellent.  Here is the summary of the article.

  1. Use the isEmpty() method of the collection.
  2. Avoid returning null to mean an empty collection.
  3. Create an empty collection using Collections.empty***() methods.
  4. Iterate through collections using the foreach form when possible.
  5. Use the proper collection, Collection, Map, Set, List.
  6. The left side is always an interface!  (So is the return type of methods.)
  7. If you’re explicitly casting, chances are something is wrong. Use generics.

Trim White Space from JSP

Untitled | FlickrSometimes the resultant HTML from JSP files has too much white space.  This is because a lot of JSP logic will result in only a few lines of actual HTML code and the rest is white space.

One efficient way to get rid of white space is to add this configuration to your web.xml on Tomcat/JBoss as described in this article, Trim Spaces in your JSP’s HTML.

/jboss/jboss-eap-4.2/jboss-as/server/atg/deploy/jboss-web.deployer/conf/web.xml
OR
/jboss/jboss-eap-5.1/jboss-as/server/atg/deployers/jbossweb.deployer/web.xml

<servlet>
    <servlet-name>jsp</servlet-name>
    ...

    <init-param>
        <param-name>trimSpaces</param-name>
        <param-value>true</param-value>
    </init-param>

    ...
</servlet>


However this sometimes has undesired side-effects. For example this DSP:

<div class="foo">
  <dspel:valueof param="displayName" />
</div>


causes this undesired result:

<div class="foo"/>
  Frank Kim


The work around is to do this.

<dspel:getvalueof  var="displayName" param="displayName" />
<div  class="foo"><c:out  value="${displayName}"/></div>

Update 06-09-2010: The above problem might have been happening because we were running with a version of ATG that is for Servlet 2.3. When we run with a version of JBoss that runs with Servlet 2.4, e.g.  ATG 9.1 with JBoss EAP 4.2, we no longer see this problem.

There is another tip on removing white space in this JSP FAQ: Why I am getting extra whitespace in the output of my JSP?  In our code we had one file which included a bunch of tag libraries.  It originally looked like this.

<%/** Taglibs.jsp: include to pull in all taglibs */%>

<%@ taglib uri="/dspELTaglib" prefix="dspel" %>
<%@ taglib uri="/jstlCoreTaglib" prefix="c" %>
<%@ taglib uri="/struts-bean" prefix="bean" %>
<%@ taglib uri="/struts-tiles" prefix="tiles" %


When we changed it to this we saved about 5% in terms of page size in bytes.

<%@ taglib uri="/dspELTaglib" prefix="dspel"
%><%@ taglib uri="/jstlCoreTaglib" prefix="c"
%><%@ taglib uri="/struts-bean" prefix="bean"
%><%@ taglib uri="/struts-tiles" prefix="tiles" %>


You can use this tip with a DSP page and maintain indentation.

<dspel:page    ><dspel:droplet name="/betweengo/droplet/Foo"      ><dspel:oparam name="output"        >Name: <dspel:valueof param="name"      /></dspel:oparam    ></dspel:droplet
></dspel:page>