ZK

27. October, 2011

I’ve been developing web applications for the past few years. Recently, we evaluated many of the web frameworks out there to select one for the next major release of our product.

We looked at Wicket, GWT, Vaadin, ZK, Roo and a couple of others.

Wicket was quickly dropped from the list. It’s a nice framework but it lacks one important feature: A library of reusable, cross browser components. Yeah, there are a couple but they are all very basic and building complex UIs with Wicket is done in HTML and that’s just painful.

Roo is too slow and immature and suffers from the same problems as Wicket. Maintaining cross-browser compatibility for a complex web application is something that a small team of developers can’t do anymore today.

GWT was dropped because Vaadin is based on it.

That left Vaadin and ZK.

Vaadin looks good, it’s free and based on GWT which is backed by Google. The main issue with Vaadin is that the technology is … unapproachable. There is a decent set of components but tweaking them is a pain. Plus the Java -> JavaScript compilation takes a lot of time. It’s better than most other frameworks but doesn’t compare to ZK.

Why?

ZK has a big set of well designed components with a huge documentation how to tweak them. The docs explain in detail how the components are built from HTML elements, which CSS styles are used and how you can override them. There is even a visual CSS editor that helps doing this.

When working with ZK, you often run into situations where something doesn’t work but so far, I’ve found a good solution within a short time. This might also be possible with Vaadin but it didn’t happen for me.

There are a lot of powerful layouts to arrange your UIs. You can cleanly mix ZUL (the UI descriptions) with Java code to get the best from both worlds: A clean UI description and compact code to attach listeners, publish events and connect components.

Also, ZK hides the request cycle. This is one of the biggest source of problems with developers. Yeah, the request/response cycle makes it easier to write web browsers and server frameworks but it’s a major pain for application developers. With ZK, you’re writing code that looks like a desktop application. It’s a bit like GWT in this respect but GWT feels … “proprietary”. In ZK, a lot of the API is public. In GWT, a lot of the API is hidden away in final static factory methods buried in calls between 50 classes.

You can use JavaScript but the JavaScript isn’t hidden in pseudo-native functions. That ZK5 is based on jQuery is an additional bonus if you really need to get your hands dirty.

The demo page contains lots of useful examples (instead of simply listing the available components like many other frameworks). There is a sandbox where you can modify small ZK projects online.

ZK does have its share of problems, too. Testing is a weak point. Selenium probably works well enough for mouse-driven apps but if you have components which can be controlled by keyboard alone, Selenium doesn’t cut.

The documentation on the web site could be better; for beginners, it’s especially confusing that the documentation for ZK3 and ZK5 is hard to tell apart.

But all in all, I’ve been faster to solve any problem I’ve had so far with ZK than with any other web framework.

Well done.


Making web development a bit more simple

3. January, 2010

When someone starts to make a path, most people tend to follow the trail. So when Sun introduced the Servlet API, most people were uneasy about the design problems:

  • Servlets are singletons (which are evil; this is due to performance problems in Java 1.2 which have been fixed about ten years ago).
  • The resulting code smells (feature envy since you call many methods of HttpServletRequest/Response, long method since you can’t call subdivide the doGet() without passing at least two parameters to each new method, duplicated code since you have to walk instance trees to get at a lot of information, …)

Whenever I see Java servlet code, I always wonder why people don’t solve this. It’s so simple:

public abstract class ServletRequestHandler {
    protected HttpServlet servlet;
    protected HttpServletRequest request;
    protected HttpServletResponse response;
    protected String contentType = "text/html";

    public void init(
        HttpServlet servlet, 
        HttpServletRequest request, 
        HttpServletResponse response
    ) {
        this.servlet = servlet;
        this.request = request;
        this.response = response;
    }

    public abstract void process();

    public PrintWriter out() {
        if( null == out ) {
            response.setContentType( contentType );
            
            try {
                out = response.getWriter();
            } catch( IOException e ) {
                throw new RuntimeException( 
                    "Can't get writer", e 
                );
            }
        }
        return out;
    }
    
    public ServletRequestHandler html( String html ) {
        out().print( html );
        return this;
    }
    
    public ServletRequestHandler attribute( String value ) {
        out().print( escape( value ) );
        return this;
    }
    
    public ServletRequestHandler attribute(
        String name,
        String value
    ) {
        if( StringUtils.isBlank( value ) ) {
            return this;
        }
        
        PrintWriter out = out();
        out.print( ' ' );
        out.print( name );
        out.print( "=\"" );
        out.print( escape( value ) );
        out.print( "\"" );
        return this;
    }
    
    public ServletRequestHandler text( String value ) {
        out().print( escape( value ) );
        return this;
    }
    
    // Add more methods to support your favorite
    // web design patterns
}

Now, all your servlets look the same: They accept the request, create a new instance of the right implementation of ServletRequestHandler, and call init() plus process(). With a bit of glue code, you can even use Spring to manage all your servlets for you. No more dabbling with web.xml!

And the best part: This pattern allows you to test the servlet code from a unit test without any container. Just use Spring or Mockrunner to get mock-ups for the J2EE API classes.