The Source for Java Technology Collaboration
User: Password:



Simon Brown's Blog

J2EE Archives


Comparing webapp frameworks : WebWork

Posted by simongbrown on March 24, 2006 at 03:02 PM | Permalink | Comments (5)

Like Struts, WebWork is a framework that is fairly established within the J2EE webapp space although it's interesting that I've only ever come across two types of WebWork users - those that have never heard of it and those that love it. WebWork, like most other frameworks, is designed around the web MVC pattern and uses the command and controller implementation strategy. What's slightly different about WebWork is that it's built on top of XWork, a separate framework that provides an implementation of the command pattern that is independent of the Servlet API.

In XWork, actions (or commands, depending on your terminology) implement the com.opensymphony.xwork.Action interface, which specifies a single zero argument method called execute(). Since this same interface is used in WebWork, it's possible to write actions without knowledge that they are even running within the context of a web application. From a testability perspective this is very desirable since it allows you to simply instantiate actions and execute them. Of course, most actions typically tend to operate upon data provided as parameters in the HTTP request and, like Stripes, WebWork actions declare their dependency on those parameters by providing JavaBeans style properties with the same names. At runtime, WebWork automatically extracts parameters from the HTTP request and injects them into your actions. While you can get access to the Servlet API inside of a WebWork action, WebWork doesn't force this upon you, leaving that choice to you as the developer.

Right, let's get on with seeing how a WebWork implementation of the sample application compares to the others. I'm using WebWork 2.1.7 and installing it is a simple matter of copying a few JAR files into the /WEB-INF/lib directory and adding the front controller component and WebWork tag library into the web.xml file as follows.

<servlet>
  <servlet-name>webwork</servlet-name>
  <servlet-class>com.opensymphony.webwork.dispatcher.ServletDispatcher</servlet-class>
  <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
  <servlet-name>webwork</servlet-name>
  <url-pattern>*.action</url-pattern>
</servlet-mapping>

<taglib>
  <taglib-uri>webwork</taglib-uri>
  <taglib-location>/WEB-INF/lib/webwork-2.1.7.jar</taglib-location>
</taglib>

Two additional configuration files that we need are called validators.xml and xwork.xml. The first of these defines a number of validator components that can be used by the framework to validate incoming requests through an interceptor. Each action can define it's own set of specific validation rules based upon the validators configured in the validators.xml file. Since this is a readonly webapp, we don't really have any need for validation, but we'll be coming back to this when we add some user interactivity. For now, we don't need to declare any validators so the file looks as follows.

<!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0//EN"
    "http://www.opensymphony.com/xwork/xwork-validator-1.0.dtd"> 

<validators> 
</validators>

The other file (xwork.xml) defines the actions that our web application will use, along with their outcomes/results and the type of view component that is responsible for rendering those outcomes. If you've read Comparing Webapp Frameworks : Struts or are familiar with Struts, you can think of this as being similar to the struts-config.xml file. Let's see this in action by diving into the code.

Home page
The home page presents the user a list of recent blog entries and with WebWork, the code that finds these blog entries get wrappeds up inside an XWork action as follows.

package action;

import com.opensymphony.xwork.ActionSupport;
import domain.Blog;
import domain.BlogService;

/**
 * Action responsible for finding blog entries, ready to be displayed.
 *
 * @author    Simon Brown
 */
public class ViewBlogEntriesAction extends ActionSupport {

  /** the blog that owns the blog entries */
  private Blog blog;

  /**
   * Performs the processing associated with this action.
   *
   * @return  a String defining the outcome of this action
   */
  public String execute() throws Exception {

    BlogService blogService = new BlogService();
    this.blog = blogService.getBlog();

    return SUCCESS;
  }

  /**
   * Gets the blog that this action is operating upon.
   *
   * @return  a Blog instance
   */
  public Blog getBlog() {
    return blog;
  }

}

This implementation is very straightforward, just looking up the Blog instance and returning the predefined SUCCESS outcome. Notice here that the Blog instance isn't inserted into the HTTP request. Instead it's assigned to an instance variable and we'll be seeing shortly how exactly this is used in the JSP page representing the view. Speaking of which, how does the SUCCESS outcome get mapped to that JSP? Here's where the xwork.xml file fits in.

<!DOCTYPE xwork PUBLIC "-//OpenSymphony Group//XWork 1.0//EN" 
  "http://www.opensymphony.com/xwork/xwork-1.0.dtd">

<xwork>
  <include file="webwork-default.xml" />

  <package name="default" extends="webwork-default">

    <default-interceptor-ref name="defaultStack" />

    <action name="viewBlogEntries" class="action.ViewBlogEntriesAction">
        <result name="success" type="dispatcher">viewBlogEntries.jsp</result>
    </action>

  </package>
</xwork>

Here, an action called viewBlogEntries is defined (which maps onto a URI of /viewBlogEntries.action) and given the fully qualified name of the class that implements the action. In addition to this, the possible outcomes of the action are defined, mapping a simple string value onto the name of the JSP page that is responsible for rendering that particular outcome. The value of the type attribute instructs WebWork to use the Servlet request dispatcher and, as we'll see in the next blog entry, there are some other possible values that allow you to use alternative view technologies. So, what does the JSP page look like? Well it's pretty similar to the previous versions although I've chosen to show the WebWork tag library in use. It is also possible to use a pure JSP/JSTL combination.

<%@ page contentType="text/html;charset=UTF-8" %>
<%@ taglib uri="webwork" prefix="ww" %>
<%@ taglib uri="http://java.sun.com/jstl/fmt_rt" prefix="fmt" %>

<!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">

  <head>
    <title><ww:property value="blog.name" /></title>
    <link rel="stylesheet" href="screen.css" type="text/css" />
  </head>

  <body>
    <div id="container">
      <h1><ww:property value="blog.name" /></h1>
      <h2><ww:property value="blog.description" /></h2>

      <ww:iterator id="blogEntry" value="blog.blogEntries">
        <div class="blogEntry">
          <h3><ww:property value="title"/></h3>

          <ww:if test="excerpt != null">
            <ww:property value="excerpt"/>
            <p>
            <a href="<ww:url value="'viewBlogEntry.action'">
              <ww:param name="'id'" value="id"/>
            </ww:url>">Read more</a>
            </p>
          </ww:if>
          <ww:else>
            <ww:property value="body"/>
          </ww:else>

          <p>
            Posted on <ww:property value="date" />
          </p>
        </div>
      </ww:iterator>
    </div>
  </body>

</html>

If you're familiar with something like the Struts bean/logic tags or JSTL, you'll probably pick up the WebWork tags pretty quickly. ww:property outputs the value of the named property, ww:if lets you perform conditional logic and ww:iterator provides a simple looping mechanism. You may be wondering exactly where the blog object comes from since we never injected it into the HTTP request or the JSP page. Behind the scenes, WebWork uses something called a Value Stack to maintain references to objects and make them available within the various supported view technologies. You can think of the value stack as a collection of objects, and one of those objects is the action that was responsible for dispatching us to the page. Accessing objects within the stack is achieved using a language called OGNL (the Object Graph Navigation Language). During the dispatching process, the action becomes the "root" node, meaning you can easily access any properties of the action with a simple object.property syntax. Something worth pointing out is that when you use the ww:iterate tag, the "current object" in the value stack changes to reflect the current object exposed during iteration, but you can get back to any object in the stack by prefixing the expression with the # character.

Blog entry detail page
At a high level, that's pretty much it so it won't surprise you that the blog entry detail page is very similar. First the action class.

package action;

import com.opensymphony.xwork.ActionSupport;
import domain.Blog;
import domain.BlogEntry;
import domain.BlogService;

/**
 * Responsible for finding a specific blog entry.
 *
 * @author    Simon Brown
 */
public class ViewBlogEntryAction extends ActionSupport {

  /** the ID of the blog entry to display */
  private String id;

  /** the blog that owns the blog entries */
  private Blog blog;

  /** the blog entry to be displayed */
  private BlogEntry blogEntry;

  /**
   * Performs the processing associated with this action.
   *
   * @return  a String defining the outcome of this action
   */
  public String execute() throws Exception {
    BlogService blogService = new BlogService();
    blog = blogService.getBlog();
    blogEntry = blog.getBlogEntry(id);

    if (blogEntry == null) {
      return "notfound";
    } else {
      return SUCCESS;
    }
  }

  /**
   * Setter for the id property.
   *
   * @param id    a String
   */
  public void setId(String id) {
    this.id = id;
  }

  /**
   * Gets the blog that this action is operating upon.
   *
   * @return  a Blog instance
   */
  public Blog getBlog() {
    return blog;
  }

  /**
   * Gets the blog entry to be displayed.
   *
   * @return  a BlogEntry instance
   */
  public BlogEntry getBlogEntry() {
    return blogEntry;
  }

}

Next up is the fragment of XML that needs to be inserted into the xwork.xml file to register the action and define its outcomes.

    <action name="viewBlogEntry" class="action.ViewBlogEntryAction">
      <result name="success" type="dispatcher">viewBlogEntry.jsp</result>
      <result name="notfound" type="dispatcher">404.jsp</result>
    </action>

And finally is the JSP page itself.

<%@ page contentType="text/html;charset=UTF-8" %>
<%@ taglib uri="webwork" prefix="ww" %>
<%@ taglib uri="http://java.sun.com/jstl/fmt_rt" prefix="fmt" %>

<!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">

  <head>
    <title><ww:property value="blogEntry.title" /> : <ww:property value="blog.name" /></title>
    <link rel="stylesheet" href="screen.css" type="text/css" />
  </head>

  <body>
    <div id="container">
      <h1><ww:property value="blog.name" /></h1>
      <h2><ww:property value="blog.description" /></h2>

      <div class="blogEntry">
        <h3><ww:property value="blogEntry.title" /></h3>

        <ww:property value="blogEntry.body" />

        <p>
        Posted on <ww:property value="blogEntry.date" />
        </p>
      </div>
    </div>
  </body>

</html>

Summary
Where actions in frameworks like Struts only have responsibility for the business logic associated with processing a request, in WebWork (and Stripes) those actions also act as custodians for the data used in processing the request. Incoming data on the request gets automatically mapped onto JavaBean properties on the action class, which can subsequently be accessed and displayed in the various view technologies. If you're not used to this approach, it can seem a little odd at first. However, it doesn't take very long to get used to and having both the logic and data in the same place proves very useful to support a hierarchy of similar actions. All in all, WebWork is a very sophisticated web application framework that lets you build easily testable actions and provides a way for you to use multiple view technologies. In the next comparison, we'll take a break from JSP to look at another WebWork implementation that uses Velocity.



Comparing webapp frameworks : Wicket

Posted by simongbrown on March 09, 2006 at 01:53 AM | Permalink | Comments (3)

Guillermo Castro has posted a Wicket implementation of the webapp comparison that I started a while ago. It's an interesting read and the contrast with most page/request based webapp frameworks is amazing. In summary, Guillermo says:

Wicket, in my opinion, focuses the development efforts in the right place, inside plain Java code, and leaves the graphical presentation where it should be, inside html. At first you might find a little hard to grasp this paradigm shift, as so many developers are being 'forced' to rely on jstl and jsp scriptlets to accomplish logic programming for a page with all the other frameworks. But once you get used to this, I'm sure wicket will provide really fast development times.

From my perspective, the thing that I really like about Wicket is that way that you can build common components, as illustrated by the BasePage class. This is a really neat way of building in commality across many pages in terms of their content and their layout. The thing I find most interesting about the Wicket implementation is summed up by the following comment that was left on Guillermo's blog.

I've never seen a finer explanation of why Java web development takes forever.

One of the reasons that I wanted to compare frameworks with a simple read-only app is because I wanted to see whether the easy stuff was actually easy, and I've taken a lot of flak about this. From a newcomers perspective, Wicket *looks* complicated. Once I (eventually!) get a few more frameworks written up, I'll add some read/write behaviour into the application and hopefully we'll start to see some of Wicket's strengths shine through.

My thanks go to Guillermo for volunteering to do this. I have the WebWork and Stripes versions half written up, so I'll make an effort to getting these out as soon as possible. If anybody would like to volunteer to provide a similar implementation in other webapp frameworks, please get in touch and I'll e-mail you the source. If you don't have a website/blog, I'm more than happy to publish it on my blog for you.



Comparing webapp frameworks : Struts

Posted by simongbrown on January 26, 2006 at 09:48 AM | Permalink | Comments (4)

Struts is the grandaddy of Java webapp frameworks so it's fitting that we start our tour here. I think it's probably safe to say that Struts was the first model 2 (web MVC) framework to gain widespread adoption in the Java arena and to this day it's still used by many people.

Just to ensure everybody is up to speed, model 2/web MVC is an architectural pattern that promotes separation of concerns between the model, the view and the controller in a web environment. As we saw in the previous model 1 implementations of the sample application, each of the JSP pages contains Java code to lookup data and display it to the user. With an MVC approach, each of the components has a strict responsibility as follows.

  • Model : represents the data being viewed/manipulated.
  • View : responsible for rendering the model back to the user.
  • Controller : responsible for taking the request/user input and initialising the model, manipulating it, etc.

In reality, different people have different views as to whether the controller represents only the web specific parts of the process flow and whether real business logic in fact resides in the model (it being a model of the underlying business). What's important here is that web MVC promotes a separation of concerns through reusable and testable components, regardless of how you cut it. For more information about the model 2 architecture, take a look at Designing Web Applications and Servlet Patterns.

Home page
So what's different between the Struts version of the example application and the original model 1 version? Remember that Java code at the top of the page? Basically, that's been moved into a Java class.

package action;

import domain.Blog;
import domain.BlogService;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ViewBlogEntriesAction extends Action {

  public ActionForward execute(ActionMapping mapping, ActionForm form,
    HttpServletRequest request, HttpServletResponse response) throws Exception {

    BlogService blogService = new BlogService();
    Blog blog = blogService.getBlog();
    request.setAttribute("blog", blog);

    return mapping.findForward("success");
  }
}

In Struts terminology, this class is called an action although you'll also see this general pattern referred to as the command pattern. At runtime, the Struts controller (a Java servlet) maps the incoming request onto an action class and calls the execute() method, which contains the (business) logic required to service the request. In the example, this logic is responsible for locating the Blog instance and making it available (via the request) so that the recent list of blog entries can be presented back to the user. As with all of the others, this example uses JSP as the view technology, although you'll notice from the code above that we don't explicitly say, "please now show JSP page X". We'll cover this shortly but for now, here's the JSP page itself.

<%@ page contentType="text/html;charset=UTF-8" %>
<%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %>
<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %>
<%@ taglib uri="http://struts.apache.org/tags-logic" prefix="logic" %>

<!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">

  <head>
    <title><bean:write name="blog" property="name" /></title>
    <link rel="stylesheet" href="screen.css" type="text/css" />
  </head>

  <body>
    <div id="container">
      <h1><bean:write name="blog" property="name" /></h1>
      <h2><bean:write name="blog" property="description" /></h2>

      <logic:iterate id="blogEntry" name="blog" property="blogEntries" >
        <div class="blogEntry">
          <h3><bean:write name="blogEntry" property="title" /></h3>
        </div>

        <logic:notEmpty name="blogEntry" property="excerpt">
          <bean:write name="blogEntry" property="excerpt" filter="false" />
          <p>
          <html:link action="viewBlogEntry" paramId="id" paramName="blogEntry" paramProperty="id">Read more</html:link>
          </p>
        </logic:notEmpty>

        <logic:empty name="blogEntry" property="excerpt">
          <bean:write name="blogEntry" property="body" filter="false" />
        </logic:empty>

        <p>
        Posted on <bean:write name="blogEntry" property="date" format="dd MMM yyyy HH:mm:ss" />
        </p>
      </logic:iterate>
    </div>
  </body>

</html>

As you can see, moving the Java code out of the page makes for a shorter JSP that looks just like regular XHTML, albeit with a few custom tags here and there. On that note, I've chosen to use Struts tags in this version of the page purely to show something a little different to last time, but you have other alternatives including the (more feature rich) JSTL tags.

So how does a request for the home page make its way through to the ViewBlogEntriesAction class? Well, the main index.jsp page contains a simple JSP forward to /viewBlogEntries.do, which is subsequently mapped to the ViewBlogEntriesAction Java class. With Struts, there are two parts to this. First of all, the mapping between *.do and the Struts front controller servlet is defined in the web.xml file, as follows.

  <servlet>
    <servlet-name>action</servlet-name>
    <servlet-class>
        org.apache.struts.action.ActionServlet
    </servlet-class>
    <init-param>
        <param-name>config</param-name>
        <param-value>
         /WEB-INF/struts-config.xml
        </param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>action</servlet-name>
    <url-pattern>*.do</url-pattern>
  </servlet-mapping>

Next, the mapping between a URL and the Java class responsible for processing that request is specified in a file called struts-config.xml that typically resides in /WEB-INF (but is configurable, as you see above). Here's the relevant part of the file that illustrates these mappings (path -> type) for the sample application.

    <action-mappings>

      <action path="/viewBlogEntries" type="action.ViewBlogEntriesAction" name="viewBlogEntries">
        <forward name="success" path="/viewBlogEntries.jsp" />
      </action>

      <action path="/viewBlogEntry" type="action.ViewBlogEntryAction" name="viewBlogEntry">
        <forward name="success" path="/viewBlogEntry.jsp" />
        <forward name="notfound" path="/404.jsp" />
      </action>

    </action-mappings>

Within each of the action mappings, you'll also notice one or forward elements and these are essentially an abstraction over the JSP that will be responsible for rendering the response. It's probably worth noting that this is just a URI, so you don't have to reference a JSP page here. If you look back to the ViewBlogEntriesAction class above, you'll see that the last line in the execute method performs mapping.findForward("success"). This says, please find the mapping called success that's defined for this action mapping and forward control to it. In this case, the viewBlogEntries.jsp page is used. This completes the picture and is the basic way that most requests in Struts are handled.

Blog entry detail page
Likewise, for the blog entry page we have an action class and a JSP page. Here's the action.

package action;

import domain.Blog;
import domain.BlogEntry;
import domain.BlogService;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ViewBlogEntryAction extends Action {

  public ActionForward execute(ActionMapping mapping, ActionForm form,
    HttpServletRequest request, HttpServletResponse response) throws Exception {

    BlogService blogService = new BlogService();
    Blog blog = blogService.getBlog();
    request.setAttribute("blog", blog);

    BlogEntry blogEntry = blog.getBlogEntry(request.getParameter("id"));
    if (blogEntry == null) {
      return mapping.findForward("notfound");
    } else {
      request.setAttribute("blogEntry", blogEntry);
      return mapping.findForward("success");
    }
  }

}

No big surprises here except that there are two possible routes through the action depending on whether the specified blog entry is found or not. And here's the JSP page used to render the successful response.

<%@ page contentType="text/html;charset=UTF-8" %>
<%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %>

<!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">

  <head>
    <title><bean:write name="blogEntry" property="title" /> : <bean:write name="blog" property="name" /></title>
    <link rel="stylesheet" href="screen.css" type="text/css" />
  </head>

  <body>
    <div id="container">
      <h1><bean:write name="blog" property="name" /></h1>
      <h2><bean:write name="blog" property="description" /></h2>

      <div class="blogEntry">
        <h3><bean:write name="blogEntry" property="title" /></h3>

        <bean:write name="blogEntry" property="body" filter="false" />

        <p>
        Posted on <bean:write name="blogEntry" property="date" format="dd MMM yyyy HH:mm:ss" />
        </p>
      </div>
    </div>
  </body>

</html>

Summary
Despite its age, Struts is still one of the mostly widely used web application frameworks and one of the top choices for teams building Java EE systems. Additionally, the overall implementation strategy (called the Command and controller strategy in Java EE pattern documentation) is probably the most pervasive in both bespoke build and, as we'll be seeing, other open source alternatives to Struts.



Comparing webapp frameworks : Model 1 with JSP XML

Posted by simongbrown on January 12, 2006 at 02:49 AM | Permalink | Comments (0)

For completeness, I wanted to show how the JSP pages from the JSTL version could be written using the JSP XML syntax. Unsurprisingly, many people don't even know of its existence and, as I've blogged before, there aren't that many situations where you'd want to use it to write pages by hand. Should you need to, here are a couple of examples of how you would go about it using the XML syntax.

Home page
Here's the home page once again, implemented using the JSTL and written in the JSP XML syntax.

<?xml version="1.0" encoding="UTF-8"?>
<jsp:root xmlns="http://www.w3.org/1999/xhtml"
   xmlns:jsp="http://java.sun.com/JSP/Page"
   xmlns:c="http://java.sun.com/jstl/core_rt"
   xmlns:fmt="http://java.sun.com/jstl/fmt_rt"
   version="2.0">

  <jsp:useBean id="blogService" scope="request" class="domain.BlogService"/>
  <c:set var="blog" value="${blogService.blog}" />

  <jsp:output doctype-root-element="html"
    doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN"
    doctype-system="http://www.w3c.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"/>
  <jsp:directive.page contentType="text/html;charset=UTF-8" />

  <html xmlns="http://www.w3.org/1999/xhtml">

    <head>
      <title>${blog.name}</title>
      <link rel="stylesheet" href="screen.css" type="text/css" />
    </head>

    <body>
      <div id="container">
        <h1>${blog.name}</h1>
        <h2>${blog.description}</h2>

        <c:forEach var="blogEntry" items="${blog.blogEntries}">
          <div class="blogEntry">
            <h3>${blogEntry.title}</h3>

            <c:choose>
              <c:when test="${not empty blogEntry.excerpt}">
                ${blogEntry.excerpt}
                <p>
                <a href="viewBlogEntry.jsp?id=${blogEntry.id}">Read more</a>
                </p>
              </c:when>
              <c:otherwise>
                ${blogEntry.body}
              </c:otherwise>
            </c:choose>

            <p>
            Posted on <fmt:formatDate value="${blogEntry.date}"
                        timeZone="${blog.timeZone}" type="both"
                        dateStyle="long" timeStyle="long" />
            </p>
          </div>
        </c:forEach>
      </div>
    </body>

  </html>

</jsp:root>

In comparison to the previous implementation, the major difference here is that the JSP page must be well formed XML, with everything wrapped up inside a <jsp:root> element. In addition, the taglib directives are replaced by a simple XML namespace, which is really quite neat.

Blog entry detail page
The blog entry detail page is fairly similar in all respects, with the Java code at the top of the page now being wrapped up inside a <jsp:scriptlet> element.

<?xml version="1.0" encoding="UTF-8"?>
<jsp:root xmlns="http://www.w3.org/1999/xhtml"
   xmlns:jsp="http://java.sun.com/JSP/Page"
   xmlns:c="http://java.sun.com/jstl/core_rt"
   xmlns:fmt="http://java.sun.com/jstl/fmt_rt"
   version="2.0">

  <jsp:output doctype-root-element="html"
    doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN"
    doctype-system="http://www.w3c.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"/>
  <jsp:directive.page contentType="text/html;charset=UTF-8" />
  <jsp:directive.page import="domain.*" />

  <jsp:scriptlet>
    BlogService blogService = new BlogService();
    Blog blog = blogService.getBlog();
    request.setAttribute("blog", blog);

    BlogEntry blogEntry = blog.getBlogEntry(request.getParameter("id"));
    if (blogEntry == null) {
      response.sendError(HttpServletResponse.SC_NOT_FOUND);
      return;
    } else {
      request.setAttribute("blogEntry", blogEntry);
    }
  </jsp:scriptlet>

  <html xmlns="http://www.w3.org/1999/xhtml">

    <head>
      <title>${blogEntry.title} : ${blog.name}</title>
      <link rel="stylesheet" href="screen.css" type="text/css" />
    </head>

    <body>
      <div id="container">
        <h1>${blog.name}</h1>
        <h2>${blog.description}</h2>

        <div class="blogEntry">
          <h3>${blogEntry.title}</h3>

          ${blogEntry.body}

          <p>
          Posted on <fmt:formatDate value="${blogEntry.date}"
                      timeZone="${blog.timeZone}" type="both"
                      dateStyle="long" timeStyle="long" />
          </p>
        </div>
      </div>
    </body>

  </html>

</jsp:root>

Summary
All in all, there aren't massive changes between writing a page in the native JSP syntax and writing it in the XML syntax, but care does have to be taken to ensure that your JSP pages are valid XML and easily readable if using the latter. Personally, I've never seen the XML syntax in use on projects that I've been involved with but the choice, as they say, is yours.

Right, let's put model 1 behind us and start comparing some webapp frameworks. :-)



Comparing webapp frameworks : Model 1 with JSTL

Posted by simongbrown on January 10, 2006 at 09:05 AM | Permalink | Comments (2)

It's been a while since the last blog entry, but let's continue our look at the webapp frameworks with another model 1 implementation, this time using the JavaServer Pages Standard Tag Library (JSTL).

In Comparing webapp frameworks : Model 1 with scriptlets we saw that model 1 applications typically have some boilerplate code at the top of the page to "set the scene" and the use of scriptlets means short pieces of Java code scattered throughout the page to control the presentation logic. As an alternative to this, we could use the JSTL.

Home page
Here's the home page, implemented using the JSTL.

<%@ page contentType="text/html;charset=UTF-8" %>
<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jstl/fmt_rt" prefix="fmt" %>

<jsp:useBean id="blogService" scope="request" class="domain.BlogService"/>
<c:set var="blog" value="${blogService.blog}" />

<!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">

  <head>
    <title>${blog.name}</title>
    <link rel="stylesheet" href="screen.css" type="text/css" />
  </head>

  <body>
    <div id="container">
      <h1>${blog.name}</h1>
      <h2>${blog.description}</h2>

      <c:forEach var="blogEntry" items="${blog.blogEntries}">
        <div class="blogEntry">
          <h3>${blogEntry.title}</h3>

          <c:choose>
            <c:when test="${not empty blogEntry.excerpt}">
              ${blogEntry.excerpt}
              <p>
              <a href="viewBlogEntry.jsp?id=${blogEntry.id}">Read more</a>
              </p>
            </c:when>
            <c:otherwise>
              ${blogEntry.body}
            </c:otherwise>
          </c:choose>

          <p>
          Posted on <fmt:formatDate value="${blogEntry.date}"
                      timeZone="${blog.timeZone}" type="both"
                      dateStyle="long" timeStyle="long" />
          </p>
        </div>
      </c:forEach>
    </div>
  </body>

</html>

As you can see, the boilerplate code at the top of the page to locate the Blog instance has been replaced with a simple JSTL tag and access to all properties on blog is performed using the JSP expression language ${...} construct, which is very succinct. In addition, the code that handles the presentation logic of iteration, conditional output and formatting has also been replaced by some JSTL tags. Line for line, this version is shorter and more readable than the previous one.

Blog entry detail page
The blog entry detail page also benefits from using the JSTL, although the scriptlet at the top of the page to locate the required blog entry is actually longer than before in order to make the objects available to the JSTL tags.

<%@ page import="domain.*" %>
<%@ page contentType="text/html;charset=UTF-8" %>
<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jstl/fmt_rt" prefix="fmt" %>

<%
  BlogService blogService = new BlogService();
  Blog blog = blogService.getBlog();
  request.setAttribute("blog", blog);

  BlogEntry blogEntry = blog.getBlogEntry(request.getParameter("id"));
  if (blogEntry == null) {
    response.sendError(HttpServletResponse.SC_NOT_FOUND);
    return;
  } else {
    request.setAttribute("blogEntry", blogEntry);
  }
%>

<!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">

  <head>
    <title>${blogEntry.title} : ${blog.name}</title>
    <link rel="stylesheet" href="screen.css" type="text/css" />
  </head>

  <body>
    <div id="container">
      <h1>${blog.name}</h1>
      <h2>${blog.description}</h2>

      <div class="blogEntry">
        <h3>${blogEntry.title}</h3>

        ${blogEntry.body}

        <p>
        Posted on <fmt:formatDate value="${blogEntry.date}"
                    timeZone="${blog.timeZone}" type="both"
                    dateStyle="long" timeStyle="long" />
        </p>
      </div>
    </div>
  </body>

</html>

Summary
As this example shows, the JSTL can be used to considerably reduce the need for Java code but ultimately the overall design of a model 1 page is still the same. It's hard to get away from having a block of Java code at the top of the page where processing needs to happen before the page is rendered. A good example is the blog entry detail page that looks up a blog entry given a specific ID. Next time, we'll look at a slightly different way to write the pages.



Comparing webapp frameworks : Model 1 with scriptlets

Posted by simongbrown on November 23, 2005 at 11:42 AM | Permalink | Comments (1)

Before we dive into the frameworks, I want to drop back to basics to give some context behind why the frameworks exist and what benefits they provide. For this reason, let's look at a naive model 1 implementation of the sample application. If you're already familiar with the whole model 1 vs. model 2 thing, you might want to skip reading this particular entry.

Overview
An in-depth explanation of model 1 vs. model 2 can be found in Designing Web Applications and Servlet Patterns, but essentially a model 1 web application architecture is where all of your logic is wrapped up inside the pages of your application. By logic, I'm referring to things like business logic, presentation logic and page flow. Let's take a look at some examples of this by seeing how a model 1 version of the sample application might be built.

Home page
From a JSP perspective, a model 1 web application is very easy to build because you just start coding away in your JSP pages. Here's what the home page looks like when implemented using a model 1 architecture.

<%@ page contentType="text/html;charset=UTF-8" %>
<%@ page import="domain.*,
                 java.util.Iterator,
                 java.text.DateFormat" %>
<%
  BlogService blogService = new BlogService();
  Blog blog = blogService.getBlog();
%>

<!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">

  <head>
    <title><%= blog.getName() %></title>
    <link rel="stylesheet" href="screen.css" type="text/css" />
  </head>

  <body>
    <div id="container">
      <h1><%= blog.getName() %></h1>
      <h2><%= blog.getDescription() %></h2>

      <%
        Iterator it = blog.getBlogEntries().iterator();
        while (it.hasNext()) {
          BlogEntry blogEntry = (BlogEntry)it.next();
      %>
        <div class="blogEntry">
          <h3><%= blogEntry.getTitle() %></h3>

          <%
            if (blogEntry.getExcerpt() != null) {
          %>
            <%= blogEntry.getExcerpt() %>
            <p>
            <a href="viewBlogEntry.jsp?id=<%= blogEntry.getId()%>">Read more</a>
            </p>
          <%
            } else {
          %>
            <%= blogEntry.getBody() %>
          <%
            }
          %>

          <p>
          <%
            DateFormat dateFormat = DateFormat.getDateTimeInstance(
              DateFormat.LONG, DateFormat.LONG, blog.getLocale());
            dateFormat.setTimeZone(blog.getTimeZone());
          %>
          Posted on <%= dateFormat.format(blogEntry.getDate()) %>
          </p>
        </div>
      <%
        }
      %>
    </div>
  </body>

</html>

I'm not going to explain each and every line, but the basic structure breaks down as follows.

  1. Define page characteristics and import Java classes.
  2. Locate the Blog instance to work with, via the BlogService.
  3. Write out the page header, title, etc.
  4. For each blog entry, write out the appropriate properties.
  5. Close all the tags.

For the "read more" link, this is simply implemented as a call to the blog entry detail JSP page, passing the blog entry ID as a parameter. Notice how this is conditionally included, depending on whether the excerpt is null - it's a good example of the simple presentation logic that you'll find in many web applications. The date formatting code is another example.

Blog entry detail page
The blog entry detail page is very similar.

<%@ page contentType="text/html;charset=UTF-8" %>
<%@ page import="domain.*,
                 java.text.DateFormat" %>
<%
  BlogService blogService = new BlogService();
  Blog blog = blogService.getBlog();
  BlogEntry blogEntry = blog.getBlogEntry(request.getParameter("id"));
  if (blogEntry == null) {
    response.sendError(HttpServletResponse.SC_NOT_FOUND);
    return;
  }
%>

<!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">

  <head>
    <title><%= blogEntry.getTitle() %> : <%= blog.getName() %></title>
    <link rel="stylesheet" href="screen.css" type="text/css" />
  </head>

  <body>
    <div id="container">
      <h1><%= blog.getName() %></h1>
      <h2><%= blog.getDescription() %></h2>

      <div class="blogEntry">
        <h3><%= blogEntry.getTitle() %></h3>

        <%= blogEntry.getBody() %>

        <p>
        <%
          DateFormat dateFormat = DateFormat.getDateTimeInstance(
            DateFormat.LONG, DateFormat.LONG, blog.getLocale());
          dateFormat.setTimeZone(blog.getTimeZone());
        %>
        Posted on <%= dateFormat.format(blogEntry.getDate()) %>
        </p>
      </div>
    </div>
  </body>

</html>

The scriptlet at the top of the page is probably the most interesting because that piece of code is responsible for locating the requested blog entry or sending the user off to an error page, which is simply configured through the web.xml file with the following XML fragment.

<error-page>
  <error-code>404</error-code>
  <location>/404.jsp</location>
</error-page>

Summary
Both pages contain a short piece of Java code at the top of the page to "set the scene". This type of logic is typically what you find scattered throughout the pages of a model 1 webapp, the downsides of which include reduced maintainability, reusability and testability. Both additionally contain several other short pieces of Java code to handle some presentation logic such as iteration, conditional processing and date formatting. As we'll see next, the JSP Standard Tag Library (JSTL) can help to solve at least some of these problems.



Comparing webapp frameworks : Domain model

Posted by simongbrown on November 09, 2005 at 04:21 AM | Permalink | Comments (1)

Before we kick off our look at webapp frameworks, let's establish the domain model we're working with. It's pretty simple - blogs and blog entries, residing in a package called domain.

Domain model : BlogService, Blog and BlogEntry

Because I want to concentrate on the presentation aspects of the frameworks this time around, I'm ignoring the persistence mechanism. Instead, I'm just assuming that data access will be achieved via a "service", regardless of whether it uses direct JDBC, a DAO, a web service, Hibernate, etc.

So that's the model. The question is, will any of the frameworks or view technologies require us to change it?



Comparing webapp frameworks : Requirements

Posted by simongbrown on November 04, 2005 at 05:45 AM | Permalink | Comments (8)

So, to compare webapp frameworks we need an example web application. I've chosen to build a simple blog. Here are the functional requirements.

  1. The home page will display a list of the 3 most recent blog entries, in reverse chronological order. The following information will be displayed for each blog entry.
    • Title
    • If an excerpt is present, the excerpt will be displayed with a "read more" link to the full blog entry.
    • If no excerpt is present, the full body will be displayed.
    • Date/time
  2. When a "read more" link is clicked, the resulting page will display the following information about the selected blog entry.
    • Title
    • Body
    • Date/time

And here are some non-functional requirements, just to make things a little more interesting.

  1. The web application will make use of and validate against the following standards.
    • XHTML 1.0 Transitional
  2. HTTP status codes will be used where appropriate (e.g. 404 for page not found).
  3. UTF-8 will be used as the character encoding to support international character sets.
  4. Dates and times will be formatted appropriately for the locale of the owning blog.
  5. Dates and times will be presented in the time zone of the blog.
  6. A strict MVC architecture will be adopted, with all access to views being made through the controller.
  7. The technology constraints are as follows.
    • Java SE 5.0
    • Servlet 2.4 and JSP 2.0
    • Tomcat 5.5.x

Here are some screenshots to show what this all looks like.

Home page
Figure 1 : Home page.

Blog entry detail page
Figure 2 : Blog entry detail page.

Page not found page
Figure 3 : Page not found page.

As I've said before, I hoping to make this an iterative process and there's plenty of scope for adding some interactivity into the example application. Next up is a look at the domain model.



Comparing webapp frameworks : Why?

Posted by simongbrown on November 03, 2005 at 11:59 AM | Permalink | Comments (11)

After posting Comparing webapp frameworks : Introduction yesterday, I got lots of feedback - some good, some bad. So, why am I doing this?

First off, here are some of the negative comments.

  • Imho this is a complete waste of time and it will be another biased comparison without any real use whatshowever. Please spend your time on something useful and don't add another confusing hyped comparison to the mix.
  • A propos, the easy 80% is rarely the problem and often very repetitive. Most of it is even getting totally automated with CRUD frameworks. The interesting bit is the difficult 20%, this is where the actual difficulties lie and where most time is spent.
  • No one cares about how each framework handles simple things.
  • If I wanted to compare frameworls your way I'd visit every one of the frameworks web sites...
  • Many frameworks sell there idea demonstrating how easy it is to do simple stupid examples.

Fantastic! At least people are talking and I got some response. Great to see that the community is alive. :-)

Choice
When choosing a platform to build a web application, J2EE is still the first choice for many. As we're all well aware, new webapp frameworks are released fairly often and I believe that there's still a lot of room for innovation, particularly when you look "Beyond Java", with stuff like Ruby on Rails. So, from this perspective, one of the reasons that I'm doing this is to provide an "at a glance" view of many frameworks as opposed to going in deep on a few. After all, I want to be in a position to answer questions like, "do you think we should use Struts or something newer like Stripes?". I suspect that most people would comment that both are webapp frameworks, but recommend Struts because it's proven. I could be wrong, but I do think that even an "at a glance" view offers something of value.

Nobody cares about the simple stuff
Taking on the comment about the 80% being easy and repetitive - yes, that's exactly what I was getting at. It is easy, or at least it should be. That's something else that I want to look into. If a particular framework makes the easy stuff hard, I'm not going to recommend it to my clients. Where's the productivity gain in slowing 80% down but making 20% really fast? True, some of the easy stuff can be automated with CRUD style webapp frameworks, but this isn't necessarily the world we live in. Just taking an example, one of my current clients is building a web presence over the top of a service oriented architecture, which is deployed on an enterprise service bus. How do those CRUD frameworks help me here?

Consistency and reduced learning curve
Why should I have to compare frameworks by visiting each and every website? They all differ in terms of content, layout, documentation, examples, etc. By implementing even a simple application, I can reduce the learning curve for those people that just want to quickly skim the frameworks and pick up the main points. This is made even easier if the code for the same application is available for multiple frameworks.

The other thing to pick up on here is that some of the framework sites do have incredibly simple examples. They're even simpler than the application I've come up with and that's a problem. Once you stray outside of the simple example you have to start digging around the docs. If I can at least go slightly deeper than the very simple examples, again, I think this adds value.

The evolution of web MVC
Another reason for doing this is to see how the web MVC pattern has evolved over the past few years. I don't want to jump ahead too much, but there are some very interesting and unique ways that this seemingly simple pattern has been implemented. I want to compare and contrast this too. Coupled with the view technologies, I want to see how these various choices affect what is ultimately the core architecture of your web application.

Just to clarify, my sample application is read-only from the perspective of the user. The content is dynamic, but the user can't update it. As I said, I am hoping to make this an iterative process and revisit it to add further levels of detail. I've got to start somewhere though. ;-)



Comparing webapp frameworks : Introduction

Posted by simongbrown on November 02, 2005 at 12:21 PM | Permalink | Comments (9)

Struts, WebWork, Stripes, Spring MVC, Wicket, Tapestry, JSF, etc, or even rolling your own. With so many J2EE web application frameworks to choose from, how do you decide which one to use? Several articles (e.g. JavaServer Faces vs Tapestry) and presentations (e.g. Comparing Web Frameworks) already exist, but they generally concentrate on a small subset of the available frameworks.

Over the next few weeks, I'm going to implement a small web application using as many J2EE web application frameworks that I can get my hands on. I'll be using the resulting code to compare and contrast what the frameworks provide and how they work.

Clearly this is a massive task so, to reduce the scope, I'm going to focus on what it takes to build a read only web application. If I were to hazard a guess, I'd say that the 80-20 rule applies. 80% of a web application is read only and 20% is interactive (e.g. HTML forms, AJAX, etc). Of course, this is changing with technologies like AJAX, but we're still on the upward curve. Traditionally, that 20% is the most complex and is an area where many web application frameworks claim their unique selling points. For this reason, I may iterate over the evaluation process to take into account how the frameworks help web developers build interactive webapps. For now, I'm going to look at whether the frameworks make doing the 80% easy.

In addition to looking at the webapp frameworks, I'm also going to compare and contrast some of the view technologies that are currently available. Here, I'm talking about JSP (normal and XML formats), Velocity, FreeMarker, etc. I think this adds an interesting twist and your choice of view technology may have an impact on your framework decision.

Stay tuned, it should be an interesting journey!



I have Servlets

Posted by simongbrown on July 14, 2005 at 09:07 PM | Permalink | Comments (3)

In Got Servlets?, Greg is asking what we'd like to see in the next major revision of the Java Servlets specification. In no particular order, here are my initial thoughts.

  • Programmatic access to the security realm : There are more and more sites out there that offer users a way to sign up for their services and this is fairly tricky to do with the standard, declarative J2EE security model. If you know that you're using a particular platform (e.g. Tomcat), then you can write some code that takes advantage of the underlying way in which the security credentials are stored, and edit them appropriately. But what about when you're targeting more than a single application server platform? What about when your team is developing on Tomcat and deploying to WebLogic? In this situation, being able to access an abstraction of the underlying realm implementation would be very useful. Self registration then becomes much easier - create a principal, assign some roles and write it back to the underlying realm in a platform independent way. Yes, you can do this with external security frameworks, but it would be nice to have this as a part of the standard.
  • Programmatic access to the security constraints : Following on from the point above, programmatic access to the security constraints of the current web application would also be really useful. Self registration on it's own lets you build applications where the content presented to the user varies based upon who that user is. However, what you can't really do is change the security constraints of the web application on the fly. For example, imagine you're a blog hosting provider. You might want to let users self register for a public blog. On the other hand, you might want to let them register for a private blog, secured by the declarative security constraints in the web.xml file. Given the choice of using filters or security constraints in the web.xml file to permit or disallow access, I'd rather use the declarative approach because it's tried and tested code, reducing the risk that my site will be breached. This is one of the major benefits of using declarative security - the container does this work for you. Again, stopping people reinventing the wheel each time the security system doesn't work for them would be nice.
  • Specification ambiguities : Inconsistency through ambiguity is a major headache for many developers, although I'd say that it's an even bigger headache for people wanting to build J2EE applications that really can run anywhere. Take Inconsistency between Servlet specification implementations as an example. Some containers provide you information about whether a user is logged in and some don't. Things like this really do need to be addressed. At the heart of this problem are ambiguities in the specification, but I'd say that the test cases around specification compliance need to be greatly improved. After all, what's the point of having a bunch of "J2EE compatible" application servers if they are inconsistent in how they implement the specs. Greatly reduces the benefit of the certification, don't you think?
  • Regex URL patterns : The current wildcard scheme for specifying "url-pattern"s is far too limiting. Regex support would be nice, particularly now since newer versions of the J2EE spec mandate the use of versions of J2SE that contain regex support.

On a more general note, admittedly I've not used Java 5 annotations much, but I'm one of these people that is a little bit skeptical of them. They do have their uses, but I am a little concerned about them being overused, for example, to configure components through the code. Mike Spille has a great blog entry named Action Hippo Rangers! where he talks about the ping pong nature of software development. One of the examples he cites is the adoption of annotations versus XML configuration. The point is, just because XML configuration is seen as complex and verbose, this doesn't mean that we should switch everything over to annotations. Everything in moderation, otherwise we'll be campaigning for the return of the web.xml file in a couple of years! ;-)



Where are all the J2EE 1.4 implementations?

Posted by simongbrown on November 02, 2004 at 12:24 PM | Permalink | Comments (4)

It's still relatively early days for J2EE 1.4 in the real world, but compare the number of J2EE 1.4 implementations (6) with the number of J2EE 1.3 implementations (21). I remember that prior to the final J2EE 1.3 release, vendors seemed to be falling over themselves to get their implementations out but this doesn't seem to be happening anymore. Most J2EE app servers have some ability to support web services (the key addition for J2EE 1.4) so I'd be surprised if the lack of implementations is due to the complexity involved. Even JSP 2.0 and Servlet 2.4 containers were fairly thin on the ground until recently. What do you think?



Message acknowledgment and redelivery with message-driven beans

Posted by simongbrown on June 03, 2004 at 02:23 PM | Permalink | Comments (3)

We've been doing some prototyping over the past week and wanted to put together a simple enterprise application to prove some of the characteristics of JMS message processing via message-driven beans. The application server we're using is WebSphere Application Server 5.1 and for the purposes of our testing, we've been using the embedded messaging server. Although WSAD isn't my favourite tool, it does allow us to develop/deploy/test components incredibly quickly and this is great for tweaking the properties of MDB's to see how they behave differently.

One of the features that we've been playing with is the transaction demarcation on MDBs. As with session beans, you can use container-managed transactions (CMT) or bean-managed transactions (BMT). However, unlike session beans, you don't seem to be able to easily implement a functionally identical bean with CMT and BMT. It comes down to message acknowledgment.

If you have a CMT message-driven bean with the transaction attribute defined as Required, receipt and acknowledgement of the message is included within the transaction that the container starts prior to calling onMessage(). In other words, if the onMessage() method returns successfully (i.e. without an exception being thrown) and the transaction hasn't been flagged to rollback, the container will acknowledge receipt of the message for you inside the transaction. On the other hand, if an exception is thrown or you call setRollbackOnly(), the container won't acknowledge the message. When this occurs, typically the container/JMS provider will attempt to redeliver (retry) the message a short time later.

Moving on to BMT message-driven beans and things are not the same. Of course, it's the responsibility of the bean developer to create and start a transaction, but a side-effect of this is that the acknowledgment of the JMS message isn't contained within this transaction. The following paragraph from section 15.4.7, Transaction context of message-driven bean methods, of the EJB 2.0 specification does in fact make this explicit.

When a message-driven bean using bean-managed transaction demarcation uses the javax.transaction.UserTransaction interface to demarcate transactions, the message receipt that causes the bean to be invoked is not part of the transaction. If the message receipt is to be part of the transaction, container-managed transaction demarcation with the Required transaction attribute must be used.

If you think about the sequence of events and when the transaction is started, this does make sense. Unfortunately, in the next section the spec goes on to say the following.

Message-driven beans should not attempt to use the JMS API for message acknowledgment. Message acknowledgment is automatically handled by the container. If the message-driven bean uses container managed transaction demarcation, message acknowledgment is handled automatically as a part of the transaction commit. If bean managed transaction demarcation is used, the message receipt cannot be part of the bean-managed transaction, and, in this case, the receipt is acknowledged by the container.

So then, message acknowledgment is handled by the container. With CMT, a commit or rollback will effectively acknowledge or not acknowledge the message, but with BMT the message will always be acknowledged. This is a subtle point but means with BMT that if the onMessage() doesn't return successfully, the message gets acknowledged anyway and redelivery won't occur. It seems that you have to be very careful about implementing BMT message-driven beans!

The reason that we discovered this is because we were trying to figure out the best way to implement logic like, "sorry, not quite ready to process this message yet". With CMT, rolling back the transaction puts the message back on the queue ready for it to be delivered to another MDB instance and if it wasn't for the listener ports in WebSphere Application Server blowing up, we might have had a solution. Now we're exploring other options, including the usual mechanism of forwarding on the message to another (or the same) queue. We're also looking into our WebSphere listener port problem and hopefully it's just a config issue. ;-)



Inconsistency between Servlet specification implementations

Posted by simongbrown on November 27, 2003 at 03:49 AM | Permalink | Comments (3)

I’ve been playing around with the various implementations of the security features in Servlet 2.3 compatible web containers. If you’ve ever built secure web applications, you’ll know that there are a handful of fairly useful methods on the HttpServletRequest interface. For example, the getUserPrincipal() method allows you to get access to the authenticated principal, as described by the following Javadoc.

Returns a java.security.Principal object containing the name of the current authenticated user. If the user has not been authenticated, the method returns null.

The reason that I've been looking into all this in detail is that I'm trying to get my open source blogging software (Pebble) to work consistently between vendor implementations. In the webapp, I have a collection of unsecured pages and a collection of secured pages that are defined to fall within a security constraint that is declared in the web.xml file. As stated the by Servlet specification, trying access a secured resource will force the user to be authenticate themselves. The problem that I've come across is that those security methods that I mentioned before work inconsistently between implementations.

For example, on Tomcat and Resin, a call to the getUserPrincipal() method returns a non-null Principal instance at any time after authentication, regardless of whether a request has been made for a secured or unsecured resource. However, with other implementations such as JBoss and Jetty, the getUserPrincipal() method only returns a non-null instance if the request is for a secured resource. What this means is that after authentication, you cannot consistently tell from that method whether the current user has been authenticated or not. Tomcat/Resin will report yes, while JBoss/Jetty will report no.

This issue first came up because a few people have deployed my blogging webapp onto JBoss and were reporting that they could not see some of the "admin" links that appear on the top of every page after logging in. Having delved through the Servlet specification and accompanying Javadoc, I'm still not sure who has correctly implemented this particular feature. A workaround to this is fairly straightforward, and just requires that the user's credentials are saved away in the session, using something like the following:

    // some J2EE web containers don't allow programmatic access to the
    // principal information from resources that don't fall under a
    // security constraint - for this reason this information is placed into
    // the user's session
    AuthenticatedUser user = new AuthenticatedUser();
    user.setName(request.getUserPrincipal().getName());
    user.setBlogOwner(request.isUserInRole(Constants.BLOG_OWNER_ROLE));
    user.setBlogContributor(request.isUserInRole(Constants.BLOG_CONTRIBUTOR_ROLE));
    request.getSession().setAttribute(Constants.AUTHENTICATED_USER, user);

Regardless of the workaround, this does present some interesting questions. Which implementation is correct? What happens when the specification is unclear? Are the Javadocs considered as a part of the specification? After all, they are a programming contract and included in the specification itself. In this case, my opinion is that Tomcat and Resin are correct because the important point is that the user has been authenticated. What do you think, and what do you think would happen if all the implementations were put through the J2EE compatibility tests? Deploying to a certified implementation is my next step and should guarantee consistency. Perhaps making the compatibilty test kits free to open source implementations would help in situations like this, removing doubt as to what is correct.



Panther ships with Ant, XDoclet and JBoss

Posted by simongbrown on October 28, 2003 at 07:53 AM | Permalink | Comments (4)

I've just installed Panther and since you don't get stuff like CVS installed by default, I decided to open up the XCode CD and install the developer tools. To my surprise there are some Java tools tucked away including Ant, XDoclet, log4j and JBoss. If you install the Java tools, they can be found in :

  • Ant 1.5.3, XDoclet 1.2b and log4j 1.2.8 in /Developer/Java/J2EE
  • JBoss 3.2.2 (RC2) in /Library/JBoss/3.2

In Apple's inevitable way, running JBoss is as simple as navigating to the bin directory of the JBoss installation and running the run.sh script. No need to even set up environment variables such as JAVA_HOME. Okay, getting JBoss running on any platform is easy, but you have to admire Apple for making it even easier.

I knew that the server editions of Panther were going to include JBoss, but not the normal editions. Of course, you can already get newer versions of the tools yourself, but it's nice to see Apple making this stuff available and pushing Java as one of their development platforms. It just enables people to get up and running quickly, meaning that they can concentrate on learning how to develop applications rather than setting up tools. I wonder if we can convince Microsoft to include J2SE and Tomcat in the next edition of their OS? ;-)



XDoclet in the J2EE web tier

Posted by simongbrown on October 16, 2003 at 03:18 AM | Permalink | Comments (10)

It's common that you'll find somebody using XDoclet to help build their EJBs, but how often do you find people using it to help with the J2EE web tier? In his recent weblog, Dave says he is trying to convince his team that using XDoclet is the way to go for generating artefacts like tag library descriptors and the web.xml file. I must admit that while XDoclet is very useful when building EJBs, I'm not sold on the idea of using for the web tier myself. Why? Well, I think that there are several reasons for this.

For each EJB, you have to build 3 classes and the ejb-jar.xml file - all of which can be automated with XDoclet and a single source file representing the bean implementation. This is nice because the remembering all that nasty EJB deployment descriptor stuff is a pain, and everybody knows it's a pain. In one of the JavaOne sessions that I went to this year, the EJB team talked about how they were thinking of taking advantage of the new J2SE 1.5 (Tiger) feature of annotations/metedata (JSR-175) so that the deployment descriptors were automatically generated. Basically this would make XDoclet-like, attribute-oriented programming available to the J2EE platform, and that can't be a bad thing.

Another reason to use XDoclet is so that package and class names are kept in sync between the Java source and the deployment descriptors. However, when you use tools like IntelliJ to refactor a class/package name, you can ask it to look in other files too so you get the deployment descriptor refactoring for free.

I do like using XDoclet for generating the EJB stuff, but for me it doesn't add much for the web tier technologies. Are you using XDoclet in your J2EE apps? I'd be interested to hear from anybody with thoughts on this.



Integrating Tomcat and Apache on Mac OS X

Posted by simongbrown on October 13, 2003 at 02:24 PM | Permalink | Comments (3)

I've been looking at integrating Apache and Tomcat on my PowerBook so that my dev environment more closely matches the box hosting my domain. Although I really do like open source, one of the biggest problems for me is that I always seem to need software that I have to build from the original source. This is one of the reasons I bought a Mac. I have tried running some of the various Linux distros (e.g. RedHat and Mandrake) and every bit of my hardware seems to need drivers and kernels recompiled. Not my idea of fun!

Anyway, after a quick Google, I came across an article on the MacDevCenter entitled Integrating Tomcat with Apache Via the mod_jk Module. Admittedly it is slightly out of date with respect to the versions of Tomcat and mod_jk available, but the instructions do work and it has a link to download a prebuilt version of mod_jk for Mac OS X. Five minutes is all this took to get running and I didn't even have to recompile anything!



File access in EJB

Posted by simongbrown on October 08, 2003 at 11:23 AM | Permalink | Comments (5)

File access has always been a controversial activity within EJB-based applications because of the restrictions placed upon bean providers by the EJB specification. The part of the specification relevant here is under the section entitled Programming Restrictions, and it states the following about accessing the filing system.

An enterprise bean must not use the java.io package to attempt to access files and directories in the file system.

This is a fairly specific statement, and is followed up by a short explanation of why this is the case.

The file system APIs are not well-suited for business components to access data. Business components should use a resource manager API, such as JDBC, to store data.

While this explanation highlights a key reason for not using file I/O, I think that there is much more to this. However, although this is a well known restriction, actually finding more information on this is a time consuming task. So, in the quest for knowledge, I did some digging and came up with the following reasons why file I/O is "a bad thing"TM.

  1. The WORA mantra of Java and J2EE means that there might not actually be a filing system to access. I've seen various comments saying that the J2EE server might be running on some device that doesn't have a filing system, or the application server doesn't have access to the filing because it's deployed in, for example, a database server. Although this is a valid reason, I don't think that this applies to most projects.
  2. Access to files isn't transactional. Yes, typically, files aren't transational resources and when building enterprise systems, you usually want to be sure that some information has been correctly and accurately stored, hence the use of relational databases and the like.
  3. Accessing file systems is a potential security hole. If we look at how other resources (e.g. JDBC DataSources, JMS Topics, etc) are accessed, it's usually through JNDI. To ensure that only authorised parties can access these, we typically have such resources protected by some sort of authentication mechanism, be it a username/password combination, or an SSL certificate. The problem with filing systems is that they are much more open and it's harder to control access. One solution is to lock file access via the operating system, and another is to use the Java security model to restrict access to only a specific part of the disk. If you are going to access the filing system from your business components, then locking down access will help to make the system more secure and resilient to attacks.

So then, how are we supposed to access files from EJB? Many people advocate the use of an intermediary Java class to wrap up the file access, believing that the EJB specification only disallows access from the bean class itself. Is this true? I'm not convined because all the same reasons apply. The specification itself presents an answer, and that answer is to use a resource manager so that we can treat file access as a secure, transactional, pooled resource. One such implementation is a J2EE Connector Architecture (JCA) adapter that you write, deploy and configure to access your filing system. In fact, some vendors have already built JCA adapters that access flat files and these are particularly useful if you have to access the outputs of legacy, mainframe systems.

Of course, many types of file access can be worked around. For example, configuration information can be placed in LDAP, JNDI, a database, or even properties files delivered inside your JAR files that get loaded as a resource through the classloader. In those circumstances where accessing files is a requirement, then other solutions include loading the file through the servlet container, having it sent to the EJB tier via messaging, downloading the file from a webserver through a socket connection and so on.

These are all workarounds for the programming restriction but at the end of the day I think you have to be pragmatic. Many projects do utilise file access from within the EJB tier and their solutions work. Although the EJB specification imposes a restriction, in reality many vendors choose not to enforce this, meaning that using the java.io package for accessing files is possible. Whatever solution you come up with, you should ideally keep the specification in mind. It's there to help you build portable and upgradable applications, but pragmatism should be employed. Hopefully a future version of the EJB specification will address this issue in more detail and this controversy will become a thing of the past.



How do you test tag libraries?

Posted by simongbrown on October 07, 2003 at 11:58 AM | Permalink | Comments (6)

Matt is looking for a way to test tag libraries and rather than write a lengthy comment, I thought I'd follow it up here.

In the first part of his post, Matt says,

... I've looked briefly at TagUnit, but aren't you just writing JSPs (with custom tags) to test JSPs?

In answer to this question, yes, you're exactly rght in saying that you're just writing JSPs. This is the essence of TagUnit, and why I believe it's a better way to test tags than using something like Cactus. Sure, you can test the various classes with JUnit, but since you don't use the classes in this way from a JSP page, this approach can only take you so far. JSP tags are reusable components and I think that they should be tested as such. For me, this means testing those tags in the same way that they will be used on a JSP page, and that's by writing the tests and assertions as JSP pages.

Doing this has several benefits. First of all, you don't have to start mocking out parts of the servlet specification just to test the tag handlers. Instead, you're running the tests inside a real server. If you've looked into the JSP specification, you'll know that the tag lifecycle is a tricky business because of the way that JSP containers can optionally reuse and pool tag handler instances. By writing your tests as JSP pages, you instantly get all this framework for free, meaning that you can accurately test the behaviour on your desired target platform. Also, if you're aiming for cross-container compatibility, this is as simple as (in theory!) just dropping the WAR file containing the tests into a new container.

Matt wants an Ant/JUnit solution and I can see why this is desirable. I'm far more likely to run the tests if I don't have to keep starting up the JSP container. Unfortunately, there aren't many ways around this without exploring avenues such as mock objects. However, TagUnit does provide an Ant task that can be used to initiate and collect the results of running the JSP-based tests. The basics of this are documented, although this document is being expanded as we speak ... isn't it Sam? ;-) As for whether there are HTML versions of the docs ... not yet, but there might be one day.

I should probably add a disclaimer at this point, and highlight the fact that I created the TagUnit project. Clearly I'm biased, but I do think that it provides an improved way to test custom tags. Whether it's better ... that's for you to decide.



Installing Tomcat 4 as an NT service

Posted by simongbrown on September 26, 2003 at 03:57 AM | Permalink | Comments (18)

While Matt was talking about the Tomcat Service Manager, coincidentally, I was trying to install Tomcat 4 as a service on a Windows 2000 machine yesterday. For various reasons, I didn't want to install Tomcat via the .exe and therefore had to hunt around for the command line that installs the NT service. For (my) future reference, here it is, split over several lines for readability.

set JAVA_HOME=c:\j2sdk1.4.2_01
set CATALINA_HOME=c:\jakarta-tomcat-4.1.27

%CATALINA_HOME%\bin\tomcat -install "Jakarta Tomcat 4"
  %JAVA_HOME%\jre\bin\server\jvm.dll
  -Djava.class.path=%CATALINA_HOME%\bin\bootstrap.jar;%JAVA_HOME%\lib\tools.jar
  -Dcatalina.home=%CATALINA_HOME% %CATALINA_OPTS% -Xrs
  -start org.apache.catalina.startup.Bootstrap -params start
  -stop org.apache.catalina.startup.Bootstrap -params stop
  -out %CATALINA_HOME%\logs\stdout.log
  -err %CATALINA_HOME%\logs\stderr.log



Professional JSP, 3rd Edition (Apress) to be released soon

Posted by simongbrown on August 06, 2003 at 08:09 AM | Permalink | Comments (4)

Well ... it looks like our work on Professional JSP, 3rd Edition (previously titled Professional JSP 2.0, and now to be published by Apress) is almost at an end. It's currently slated for a September release and Amazon is now listing it, albeit with an incorrect authors list. I imagine that Sam, Dave, Matt and the other authors are looking forward to this being released as much as I am.

If you've not seen it, the JSP 2.0 specification provides some great new features that I think will really change the way that JSP-based web applications are developed in the future. Finally we have a native JSP expression language and this makes building templated pages much easier, without leaving the JSP environment. Another big improvement is the introduction of tag files and simple tags. These are both ways to easily build custom tags with JSP syntax or Java code respectively. Here's an early excerpt from one of my chapters back when in the days when it was going to be published by Wrox. There's some great new stuff coming our way and I can't wait for Tomcat 5 to become rolled out and production ready.





Powered by
Movable Type 3.01D
 Feed java.net RSS Feeds