Enterprise Java

ZK Web Framework Thoughts

I’ve been asked several times to present some of my opinions about ZK. So, based of my experience of 4 years as a ZK user, here’s some thoughts:

Overall developer experience, the community and documentation

“It just works”

Most of the stuff that ZK offers works very well, and the functionality is usually very intuitive to use if you have developed any desktop Java applications before. In 2007 I did a comparison of RIA technologies that included Echo2, ZK, GWT, OpenLaszlo and Flex. Echo2 and OpenLaszlo felt incomplete and buggy and didn’t seem to have proper Maven artifacts anywhere. GWT seemed more of a technical experiment than a good platform to build on. Flex was dropped because some important Maven artifacts were missing and Flash was an unrealistic requirement for the application. On the other hand, ZK felt the most “natural” and I was able to quickly get productive with it. During my 4 year long journey with ZK, I’ve gotten plenty of those “wow” moments when I’ve learned more and more of ZK and improved my architectural understanding of the framework.

Nowadays I’ve got a pretty good understanding of what in ZK works, what doesn’t, and what has problems and what doesn’t. But still, after gaining all this good and bad insight, I consider ZK to be a very impressive product out of the box. The downside of this is of course the fact that the framework hides a lot of things from newcomers in order to be easy to use, and some of these things will bite you later on, especially if your application has lots of users.

It’s very, very, very flexible

ZK is very flexible and has plenty of integrations. Do you want use declarative markup to build component trees? Use ZUL files. Do you want to stick to plain Java? Use richlets. You can also integrate JSP, JSF, Spring, and use plenty of languages in zscript. The core framework is also pretty flexible and you can override a lot of stuff if you run into problems.

The downside is that there are very many ways of doing things correctly, and even more ways of screwing up. Flexibility itself is not a negative point, but I think that the ZK documentation doesn’t guide users enough towards the best practices of ZK. What are the best practices anyway? Many tutorials use zscript, but the docs also recommend to avoid it due to performance reasons.

The forum is quite active

I think that the ZK forum is one of the best places to learn about ZK. It’s pretty active and the threads vary from beginner level to deep technical stuff. I read the forums myself almost every day and sometimes help people with their problems. There’s one thing that troubles me a bit: the English language in the forums isn’t usually very good and people often ask too broad questions. I know, it’s not fair to criticize the writings of non-native English speakers, especially when I’m not a native speaker myself. Regardless, I think that such a barrier exists. For example, take 5 random threads from the ZK forum and Spring Web forum.

The threads in the Spring forums are typically more detailed and focused instead of “I’m a newbie and I need to create application x with tons of features, please tell me how to do everything”-type threads you see in the ZK forums and people clearly spend some time formulating good and detailed questions. You’ll see that you have to spend a bit more time in the ZK forum in order to understand the threads. It’s not anybody’s fault or anything, nor a bad thing, this is just an observation. Unfortunately for me it means that some of my limited time I have for the ZK community is spent just trying to understand what people are saying. Usually I answer a thread only when I know the answer right away, or if the thread concerns some deep technical stuff.

There’s plenty of documentation

In the past the ZK documentation was scattered, out of date and some of the more important stuff was completely missing. In the recent years the docs have improved a lot, and there’s now separate comprehensive references for ZK configuration, client-side ZK, and styling. I think the documentation is today very good, and most basic questions can be easily answered by reading the docs.

As I mentioned above, ZK has a tendency to “just work”. The overall technical quality is impressive and on par with most Java web frameworks, but I believe there are some parts of ZK that are less impressive.

Stuck on Java 1.4

ZK is built with Java 1.4, which greatly limits the flexibility of their API and internal code quality

Negative effects on ZK internal code

  • ThreadLocals not removed with remove() (calling set(null) does prevent leaking the contained object but does not properly remove a ThreadLocal)!
  • Lots of custom synchronization code where simple java.util.concurrent data structures or objects would work (ConcurrentHashMap, Semaphore, Atomic*, etc)
  • StringBuffer is used where StringBuilder would be appropriate

No annotations

Personally I’m not a fan of annotation-heavy frameworks because annotations are an extralinquistic feature and usually you end up annotations with string-based values that have no type safety. However, I know that some people would be overjoyed to have an API based on them.

No enums

There are many places in the ZK API where proper enums would be much better than the hacks that are used at the moment. The worst offender is Messagebox. Just look at this signature:

public static int show(String message,
                       String title,
                       int buttons,
                       java.lang.String icon,
                       int focus)

Ugh..the magic integers remind me of SWT (which is a great library with an awful API). Let’s imagine an alternative version with enums and generics:

public static Messagebox.Button show(String message,
                       String title,
                       Set<Messagebox.Button> buttons,
                       Messagebox.Icon icon,
                       Messagebox.Button focus)

Much, much better and more typesafe. No more bitwise OR magic. I could code this in 10 minutes into ZK if it would use Java 1.5.

No generics

This is the worst part of being stuck on Java 1.4.

I’ll just list some of the places where I’d like to see generics:

Collection values in API signatures

Example in org.zkoss.zk.ui.util.Initiator:

void doInit(Page page, Map args);

vs

void doInit(Page page, Map<String, Object> args);

Example in org.zkoss.zk.ui.Component:

List getChildren();

vs

List<Component> getChildren();

Collection-like classes

Example in ListModel:

public interface ListModel {
  ...
  Object getElementAt(int index);
  ...
}

vs

public interface ListModel<T> {
  ...
  T getElementAt(int index);
  ...
}

All ListModel* classes should also be generic (most extend java.util.Collection).
org.zkoss.zk.ui.event.EventListener

public interface EventListener {
  public void onEvent(Event event);
}

vs

public interface EventListener<T extends Event> {
  public void onEvent(T event);
}

org.zkoss.zk.ui.util.GenericAutowireComposer

public class GenericAutowireComposer {
  protected Component self;
  ...
}

vs

public class GenericAutowireComposer<T extends Component> {
  protected T self;
  ...
}

All *Renderer classes
Example in org.zkoss.zul.RowRenderer:

public interface RowRenderer {
  void render(Row row, Object data);
}

vs

public interface RowRenderer<T> {
  void render(Row row, T data);
}

Unimpressive server push implementations

The default PollingServerPush has latency and will absolutely kill your application server if there are many active users. CometServerPush is better, but it does not use non-blocking IO and will block servlet threads in your servlet container. Let’s put this into perspective:

Tomcat 7.0 default configuration sets connector max threads to 200. This means that if you have 200 comet-enabled desktops, Tomcat will stop responding to other requests because all the threads are in use by comet. If the implementation used Servlet 3.0 or container-specific async APIs instead, you could run Tomcat even with one thread. It would of course be slow but it would not stop working!
Also, CometServerPush requires ZK EE so regular users are stuck with PollingServerPush. I’d say that’s a pretty big limitation considering how server push is marketed. However, it’s not surprising: proper non-blocking comet is hard to implement and requires non-blocking components in all parts of the pathway from the browser to the servlet code.

Zscript

I don’t like zscript. It might have been a good feature many years ago, but I believe that today it should not be used at all. Why, oh why would someone want to replace typesafe compiled Java code with non-typechecked zscript mixed with ZUL templates?

  • “I can use Python/Ruby/…”. This might be a valid point for some people but you’ll end up with unmaintainable code mangled inside ZUL templates
  • “Changes are visible when you save the file”. True, but I would never sacrifice so much just for this feature. And besides, you can get a similar effect with JRebel.

So, if you put “Java code” (=BeanShell code) in zscript, you might want to rethink that.

Reliance on reflection

Many useful features rely on reflection, which limits what things the compiler can check for you. This is very typical thing in many Java libraries/frameworks, so it’s not really a ZK-specific thing. As a Scala user I can see how the limitations of Java have guided most frameworks to the path of reflection/annotations. Reflection cannot always be avoided but I think it’s a bad sign if most of the useful features rely on reflection. Here are some features in ZK that use reflection:

  • Any kind of event listening that does not use component.addEventListener. This includes any classes that extend GenericEventListener (such as all ZK-provided Composer classes except MultiComposer)
  • Data binding
  • EL expressions in ZUL templates

Reference: Thoughts about the ZK Web Framework: Overall experience  & Thoughts about the ZK Web Framework: Technical stuff from our JCG partner Joonas Javanainen at the Jawsy Solutions technical blog

Related Articles :

Joonas Javanainen

Joonas is a passionate software developer from Finland. He has worked on a multitude of problem domains, and focuses professionally on functional programming and JVM-based technologies.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

4 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
diego
10 years ago

Joonas, thank you for this article!

Do you happen to have experience on PrimeFaces? I am deciding to use it or ZK and any information on this would be of great help!

CHANDU
CHANDU
9 years ago

The ZK is fully open source If yes pls leave a commant

DanDare
DanDare
8 years ago

Its been a few years, and ZK has moved on. It now has annotations and enums. Is there an updated version of this doc around? I would like to know if the performance issues for large user numbers has changed.

Filip
Filip
7 years ago
Reply to  DanDare

Dan,
ZK has indeed moved on and in a very good way.
Introduction of MVVM what makes coding even easier and faster, and performance issues are handled.
I don’t have problems with performance issues / multiple users (maybe I don’t have as much simultaneous users as you) but of course this also depends on what your hosting.

Back to top button