Thursday, November 23, 2006

AJUG Stripes Presentation

Phil Barnes and I presented the Stripes framework at AJUG last night. We wanted to spread the word about Stripes and how it simplifies Java Web development. Most of the people who attended the presentation were using Struts as their presentation framework (no surprise here). We came prepared with many examples about how Stripes compared to Struts.

I think that the presentation was well received and hopefully it will make people take another look at Stripes. We have researched many Java Web frameworks and this is probably the best one out there as far as simplicity while allowing the developer to focus on application development. Stripes uses convention over configuration for resolving URLs to action classes, has excellent databinding, and integrated well with other POJO based frameworks.

Please contact me at meagle@gmail.com if you want a copy of the slides.

Friday, April 28, 2006

Stripes: I think we have a winner!

For some time now I have been evaluating Java web frameworks. This was mostly driven by my frustration with existing frameworks I have been using. The amount of effort it takes to feed these frameworks to produce anything meaningful is usually painful and not fun to maintain. My baseline framework for Java Web development has been Struts. Struts is just outdated and requires way too many configuration files, extra classes outside the controller/action, and a separate ActionForm class that requires crude object binding. Enough said. From Struts I investigated a slew of frameworks such as Tapestry, Wicket, Spring MVC, and some JSF. These frameworks were definitely better than Struts (not too hard to achieve) but never felt much more productive and varied in learning curves. Then I started to investigate WebWork. This was definitely a step in the right direction. WebWork is an action based framework that is the basis for the Struts Action 2.0 Framework. WebWork does offer simpler actions, less configuration, some AJAX support, different view resolvers, interceptor stacks, and much more. We even decided to use WebWork for our new project after we felt that it addressed most of our concerns and there was nothing better to work with. We did experience more than a 40%+ reduction in the number lines of code and configuration files we had to write. This was great until...

The Stripes project recently released version 1.3 of their web framework. This framework relies heavily on Java 5 capabilities to deliver a much simpler web framework. The configuration is done up front in the web.xml file where a filter and a Servlet dispatcher is configured. The only thing that you need to be aware of is to configure the root package of your Stripes action classes. This allows Stripes to inspect your action classes when your servlet container starts up. Stripes uses a convention based approach to determine which classes in this defined package will be Stripes actions. Therefore, action classes do not have to be configured in an XML file. That's right - no more struts-config, xwork.xml, JSF config nonsense, etc.

From this point on you are ready to code. The action classes that you build contain concise annotations that handle interception, validation, Spring integration, and more. With your classes annotated you do not have to flip back and forth between external files and your action classes. This saves you a ton of time and reduces lines of code. In fact we migrated our WebWork code to Stripes equivalents and experienced another 20%+ reduction in the lines of code (and removing configuration files) while maintaining full functionality. Not too bad. The migration only took about 2 days to complete for about 8 complex actions and 12 JSPs. As you can see will be using this on all of our projects.

The only con I can think of for Stripes is that you have to use JSP and the Stripes taglibs. However, the taglib is pretty good and very close to HTML in regards to the naming used. I am hoping that a Velocity view resolver is on the horizon in the not too distant future. However, I did not experience too many problems with JSTL and the Stripes taglib.

If this sounds good take a look at the Stripes Quick Start Guide to quickly get up and running. Stripes is a great step forward for Java web development. It offers Java developers an simple way to program Java web applications with minimal configuration, high productivity, and a fun development framework that is addictive. This might be as close to the Ruby on Rails Action Pack for MVC development as we will see in a while from the Java community.

Tuesday, March 28, 2006

Comparing Web Frameworks: WebWork

Lately there have been Java Web framework comparisons on theServerSide.com. These comparisons revolve around requirements on Simon Brown's Blog. I am not sure that the application is very relevant and has limited functionality. However, I decided I would try this with WebWork. I have been using WebWork for about 5 months now and have been very productive with the framework's capabilities and ease of use. I took the requirements for the read only blog and reproduced it with WebWork. There is really very little that needed to be coded to make this happen and I did this on a plane trip from Atlanta to Las Vegas where I am attending TSSS with only one battery in my notebook.

To save time I copied some of the components from other people's implementations that were not framework specific.This included the domain objects Blog, BlogEntry, and BlogService. Theseare straightforward and I could have generated them in IntelliJ in about 2 minutes so no big deal. I also copied the stylesheet and image that was used to pretty up the blog look and feel. Again, no big deal and not really relevant to the framework comparison. So let me take a moment to preface some of my gripes with this little project. First, I do not consider someof the methods I used to code this application to be ideal. Since this is a read only blog application I did not use a persistence mechanism for the blog entries.

Nevertheless, I coded the application to the specifications required using only the WebWork web tier components no more. The main WebWork component that needed to be designed was the action class. This is fairly lean and should be
easy to interpret. Here is the code:

public class BlogAction implements Preparable {

private Blog blog;
private BlogEntry blogEntry;
private String blogEntryId;
private BlogService blogService;

public void prepare() throws Exception {
blog = getBlogService().getBlog();
}

public String execute() {
// simply display the default page -- the data was setup in prepare()
return "success";
}

public String viewBlogEntry() {
this.blogEntry = blog.getBlogEntry(this.blogEntryId);

return "entry";
}

public void setBlogEntryId(String blogEntryId) {
this.blogEntryId = blogEntryId;
}

public Blog getBlog() { return blog; }

public BlogEntry getBlogEntry() { return blogEntry; }

protected BlogService getBlogService() {
if (blogService == null) {
blogService = new BlogService();
}
return blogService;
}

public void setBlogService(BlogService blogService) {
this.blogService = blogService;
}

}

This is about 40 lines of code and most of that is comments, fields, and accessors. Really there are only about 5 lines of code of any logic. The prepare method is called before the action executes to setup the action. This gets called because the action implements the Preparable interface. The Prepare interceptor is invoked as one of the interceptors in the default interceptor stack. The service should really be injected into the action by an IoC container such as Spring (WebWork has good integration support with Spring). Also notice that other than implementing the Preparable interface this action is just a POJO.

Here is the action configuration in the xwork.xml file:
   <action name="Blog" class="com.meagle.wwblog.web.webwork.actions.BlogAction">
<result name="success">/pages/index.vm</result>
<result name="blogentry">/pages/entry.vm</result>
</action>
As for the views there were two files. The first one shows the blog and associated entries. I used SiteMesh todecorate the common elements and JSP as the view resolver to display the stack elements. WebWork can also use Freemarker, Velocity, and other view resolvers as well. Here is what the Sitemesh decorator looks like:
     <%@ page pageEncoding="UTF-8"%>
<%@ page contentType="text/html; charset=utf-8"%>

<%@ taglib uri="http://www.opensymphony.com/sitemesh/decorator" prefix="decorator" %>
<%@ taglib prefix="ww" uri="/webwork" %>
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xml:lang="en"
lang="en">

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title><decorator:title default="Welcome!" /></title>
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="stylesheet" href="/css/screen.css" type="text/css"/>
</head>

<body>
<div id="container">
<h1><decorator:title default="Welcome!" /></h1>

<h2><ww:property value="%{blog.description}"/></h2>

<decorator:body />
</div>
</body>

</html>

So this takes care of the blog title, name, and description that appears on each page. This also leaves a placeholder for the content of each page. Here is what was required to display the entries in the blog:

     <%@ page pageEncoding="UTF-8"%>
<%@ page contentType="text/html; charset=utf-8"%>
<%@ taglib uri="/webwork" prefix="ww" %>
<html>

<head>
<title><ww:property value="%{blog.name}"/></title>
</head>
<body>
<table>

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

<div>
<ww:if test="excerpt != null">
<ww:property value="excerpt" escape="false"/>
</ww:if>
<ww:else>
<ww:property value="body" escape="false"/>

</ww:else>
</div>

<p>
<ww:if test="excerpt != null">
<ww:url id="readMoreUrl" action="Blog!viewBlogEntry">
<ww:param name="blogEntryId" value="id"/>

</ww:url>
<a href="<ww:property value="readMoreUrl" escape="false"/>">Read More</a>
</ww:if>
</p>

<p>
Posted on <ww:date name="%{date}" format="dd MMMM yyyy hh:mm:ss z"/>
</p>
</div>
</td>
</tr>

</ww:iterator>
</table>
</body>
</html>

Again, this is straightforward and captures the requirements of the application. The only interesting lines here that allows the user to conditionally view more of a blog entry is this:

      <ww:url id="readMoreUrl" action="Blog!viewBlogEntry">
<ww:param name="blogEntryId" value="id"/>
</ww:url>
<a href="<ww:property value="readMoreUrl" escape="false"/>">Read More</a>

These lines create a link that calls the viewBlogEntry method of the Blog action by using a WebWorkconvention. The blog entry ID is appended as a parameter so that we can display the correct blog entry. You may notice the "action" in the tag references our Action class method viewBlogEntry(); it's in this method that we pull the specific entry and expose it (via a class variable) so that the view layer can render the entry. Here is the code for the view for displaying the entry.

     <%@ page pageEncoding="UTF-8"%>

<%@ page contentType="text/html; charset=utf-8"%>
<%@ taglib prefix="ww" uri="/webwork" %>
<html>
<body>
<ww:if test="blogEntry != null">
<div class="blogEntry">

<h3><ww:property value="blogEntry.title" escape="false"/></h3>

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

<p>
Posted on <ww:date name="%{blogEntry.date}" format="dd MMMM yyyy hh:mm:ss z"/>

</p>
</div>
</ww:if>
<ww:else>
<div class="blogEntry">
<h3>Sorry we could not locate that blog entry...</h3>

</div>
</ww:else>
<div><a href="JavaScript:void(0)" onclick="history.go(-1)">Back</a></div>
</body>
</html>

That is really all there was to coding the requirements of the application. The rest of the components were skeleton elements from a base WebWork configuration.

Conclusion

While this is a very simplistic web application with little functionality it does show how little coding is required by WebWork to make it happen. There is so much more that I would have like to have shown such as some of the data binding capabilities inside WebWork when submitting form information with complex object graph information.

This trivial application really does not show WebWork's full capabilities. If you think there is value in this example then you should give WebWork a try on more complex applications.
WebWork makes coding web development with Java simple and very productive with the framework's capabilities and ease of use.

Tuesday, October 25, 2005

Java Web Framework Changes...

For some time now I have been having major frustrations deciding on a Java Web framework to replace Struts. In the past I have evaluated some alternatives such as some component based Web frameworks such as Tapestry and a little at JSF. Both of these solutions are powerful but can be quite complex. While I understand the benefits of component based frameworks I am not sure that either of these frameworks are absolutely necessary for our environment. So in between Tapestry and Struts there are over 50 other web frameworks that are slight derivatives of Struts, promising frameworks like Wicket with little doco, or strangely named frameworks with little substance. So of these frameworks only two came into consideration - Spring MVC and WebWork. Both of these frameworks are not component based but address the shortcomings of Struts. One of my biggest grips with Struts is having to implement ActionForm objects and dealing with the Action class with it's hard to unit test methods. Just binding Strings to ActionForms and translating those String to my model objects is a huge coding overhead. Spring MVC and WebWork allieviate this problem and add much more value. Both have support for continuations, AJAX, good documentation, Spring integration for actions, Velocity/Freemarker support, and community support. We currently use Spring in our middle tier and Hibernate for our persistence layer. However, we chose WebWork because of the simple configuration, easy to configure interceptors, pluggable view handlers, programmable continuations, and support for other popular frameworks like Spring. Choosing a Java web framework is very difficult and you have to accept that there is no single best choice. That is probably why there are too many already available and more will keep coming until someone gets it right. So our web tier for the forseeable future will now consist of WebWork 2.2 + Freemarker + SiteMesh.

Wednesday, August 17, 2005

Is Java Dead?

I attended AJUG last night and watched Bruce Tate's presentation about 'Stretching Java'. I have to say that this was a great presentation that addressed old and new dynamic languages such as Smalltalk and Ruby. Bruce did a great job explaining the walls that we as Java developers are running up against with Web development today. Maybe Java is not the golden hammer that we thought it was for Web applications. The presentation included demonstrations with the Ruby language, the Seaside framework, and Ruby on Rails. He followed this up how Java developers need to borrow from the strengths of these technologies via techniques such as AOP, metadata/annotations, and incorporating dynamic languages (such as Jython and JRuby) that can run on a JVM. Also, continuations were covered with an example using the Ruby language. This progressed into applying the concept to handle web flows and avoiding back button issues in the browser. Rails and Seaside have native support for continuations via dynamic languages while we need to be more creative and hackish on the Java side to mimic the concept.

I have already been exposed to Ruby on Rails and I am currently reading the new Pragmatic Programmers book - 'Agile Web Development with Rails'. I am finding that this book is a good read that walks a developer through the process. It is hard to ignore technologies that are as productive as Rails when compared to what I consider a 'lightweight' Java stack to build equivalent Web applications. I consider Struts, Velocity, Spring, and Hibernate a lightweight and productive Java stack for building an end-to-end Web application. However, Web development Ruby on Rails is much faster and elegant compared to any Java stack today.

What is even more frustrating is when I read about technologies JSF. Let's see - we will build a framework (and by the way make it a standard) which is *way* fatter than something like Struts and tell developers that feeding a framework is a good thing. Rails is so much more simple and elegant that JSF from a presentation/MVC perspective. I think that Sun is making a big mistake with this framework. They finally figured out that EJB was bloated and POJOs were good. Now they are going to learn another lesson on the front end. Well, I am not following the piper this time... More than likely I will stick with my lightweight Java stack - Struts, Velocity, Spring, and Hibernate. If I need to do component development in my presentation layer I will choose Tapestry 4.

Finally, towards the end of Bruce's presentation he discussed how 2/3 of his development in mid-2006 will be non-Java. If that is not enough to make you take notice of what is going on around you then I do not know what it would take. How much more can we stretch the Java language before we turn to dynamic languages? Is Java dead or dying a slow death?