Developing Great Software

Friday, July 17, 2009

Wicket, A Stateful Web Framework

HTTP Is Stateless Desktop application programmers as well as programmers developing in a traditional multi-user, client/server environment don't normally have to worry about maintaining the state of an application's objects. After all, programming languages like C, C++, Java and C# have built-in mechanisms that maintain a variable's state during the lifetime of the application, insuring that the value of a variable is maintained and that it is 'reachable' upon referencing that variable. The stateless nature of HTTP, however, creates artificial workflows for web applications that do not exist in applications developed for the desktop or for a traditional multi-user, client/server environment. Because HTTP doesn't persist an application's state across multiple HTTP requests means that application servers and frameworks have to provide some mechanisms to allow the programmer to do this. A common method uses hash tables that are stored to physical memory or to a database or file system at the end of processing an HTTP requests. The ability to persist these values so that they can be read back when the next HTTP request hits the server for the same client session provides the glue or the narrative thread that web applications need in order to bind the multiple HTTP requests into something that simulates an unbroken (broken by HTTP request boundaries) and contiguous workflow. Managing this session state is the responsibility of the application programmer. Every application and workflow imposes its own requirements as to what and when something is required to be persisted and herein lies the problem: getting this right 100% of the time is often the most difficult challenge a developer faces when developing a web application that is maintainable, responsive and scalable. To make matters worse, the difficulty grows proportionately as the application grows in complexity and as more maintenance is done. With tight schedules and dwindling budgets there is often no time to thoroughly conduct a regression test to ensure that new bugs aren't being introduced. My own experiences working on web applications have led me to believe that this isn't the best approach to dealing with the stateless nature of HTTP and that there has to be a better way. I have spent far too many nights and weekends debugging and fixing problems related to changes made to application logic and the subsequent mismanagement of session state needed to support the work flows across multiple HTTP requests to think that this is an optimal solution. Using The Session Hash Table Perhaps now is a good time to provide an example of how hash table based session state frameworks attempt to overcome the stateless nature of HTTP and the types of problems that are associated with this technique. I will juxtapose Wicket's approach to handling this after. Lets consider what appears on the surface to be a rather simple scenario, that of maintaining and displaying a counter whose value represents the number of times the web page is processed on the server and rendered in the browser. When the user requests the web page for the first time it should be rendered displaying a value of 1 for the counter. When the user clicks the button on the web page the browser should issue a get request back to the server. The application running on the server should process the get request by incrementing the counter and rendering the page back to the browser displaying the current value of the counter. The web page itself is simple and looks like the following: The first time the user requests the page it will be rendered in the browser with a value of 1 for the counter. Each subsequent click of the button whose label is 'Click Here' will result in the browser issueing a get back to the server and the page being rendered to the browser with an incremented counter. The image below shows what the page would look like after being rendered for the second time: Notice how the counter's value in the above image is 2. This is in response to it having been incremented on the server. So what does it take code-wise on the server to provide this functionality? Using a web framework such as ASP.DotNet and ASPX Web Forms, the object associated with an aspx page would be created in response to the HTTP request and the object's load method would be called in which it would retrieve the value from the session state hash table using a string value to identify the value. It would then convert the value to an integer, increment the value by 1, convert the value back to a string, assign the value to the label on the web page, save the value to the session hash and lastly render the page back to the browser. But wait! What would happen if this is the first time the page is processing? If you didn't compensate for this and have an alternate branch of logic the named value wouldn't exist in the session hash table and the program would abort because it was attempting to manipulate a null string reference. But wait! Couldn't you instead, you ask, store the value in a field of the aspx page object and just increment it every time it processes the request? The answer is no because ASP.DotNet like many other frameworks does not persist the state of the objects that represent web pages and HTML controls on the server between HTTP requests. Instead, ASP.DotNet as do many other frameworks instantiates the object associated with the web page every time a new request arrives. Instantiation of the object causes the object's fields to be assigned their initial values according to the object constructor or to their appropriate default initial values based on their variable types. While this is a trivial example, it isn't hard to see how this way of dealing with persisting state between HTTP requests can quickly snowball out of control. Now imagine that there is a web framework out there that actually does persist the objects associated with web pages and HTML controls across HTTP requests. Suddenly, schemes such as having to save application state in hash tables and persist them across HTTP requests are no longer necessary. Now your favorite object oriented programming language behaves almost the same way in web applications as it does in desktop or client-server applications. Imagine that the fact that the web application is running in a stateless HTTP environment is hidden from the developer and the framework takes care of persisting and restoring the objects associated with your application's web pages and HTML controls for you. Enter Wicket, Simply Eloquent and Eloquently Simple Well, you are not left to your imagination because there actually is a web application framework that does this and a whole lot more for you. It is the Java based Apache Wicket web framework. Using the example from above, here is the actual code written to the Wicket web framework that renders the web page pictured above: That's it. Nowhere is there code to save or retrieve string values from a session based hash table. Nor are there alternate paths of logic needed to differentiate processing that should happen the first time a web page is being requested from all other requests. There is just "normal" Java code - i is initialized in the HomePage constructor and i is incremented in response to the button's onClick method. The current value of i is rendered back to the browser in response to each request. This style will seem very familiar to those who have coded Java SE Swing based applications or to anyone who has coded desktop applications using other programming languages such as C# or even Basic. And if you are thinking that there must be some magic happening in the HTML page well there isn't and here it is: Nothing but pure HTML. Wicket is a Model/View/Controller based framework. HTML pages never mix markup with code. They are strictly the 'view' part of the MVC equation. The actual magic is happening behind the scenes and within the Wicket framework's request cycle processing which is responsible for persisting the HomePage object at the end of each request cycle and restoring it at the start of each request cycle. This is completely transparent to the application developer who can just assume that objects behave like... objects. Wicket hides the stateless nature of HTTP and enables coding web applications like one would code non web applications. Of course the developer must exercise sound judgment when deciding what and how much to persist in the objects associated with Wicket web pages and HTML controls. Persisting a list of 100,000 database records, for instance, for thousands of concurrent users is wasteful and could cause severe degradation or even cause the server to fail altogether. For instance, persisting a database table row's unique identity in a web page object is preferable to persisting the actual row of data since the database itself already serves as the underlying cache for the data. Having the identity of the row of data is enough to allow the data to be retrieved through a query to the database when and if it is needed. Wicket also provides a model architecture that promotes this type of resource usage. Wicket's LoadableDetachableModel class provides the developer with the ability to persist only the minimum amount of information across HTTP requests - such as a data row's identity value - which can be used to query the database for the actual data when and if it is needed and released at the end of the request. Summary The Apache Wicket web framework eliminates one of the greatest challenges faced by developers of web applications, the dreaded persistence problem caused by the stateless nature of HTTP. Wicket also provides numerous other advantages to developers of web application, some of which I have already written about and which you can read here in my blog. I hope you have enjoyed reading this article as much as I have enjoyed presenting it to you. And as always, please feel free to leave your comments.

17 comments:

  1. Jeff, this is indeed very interesting, thanks for posting this. You also make excellent points about not maintaining "all" records from a database in an object, for instance. I am intrigued by how Wicket might play with CFML which renders Java bytecode.

    ReplyDelete
  2. This is a nice little article, thanks.

    Lift (http://liftweb.net) does some similar (better?) things along these lines, albeit in Scala.

    ReplyDelete
  3. Excellent article, hats off to you Jeff. I already used that framework in a small web application but I was totally unaware of its power. It sounds interesting.

    Thanks Jeff.
    Kind Regards,
    Aizaz

    ReplyDelete
  4. There are already several such component-based development frameworks for the web. JSF, for example, is well-established, has been part of the JavaEE standard itself for quite some time, and one can achieve what all has been present above using JSF. Why should one choose Wicket for doing this, over an existing standard framework such as JSF?

    ReplyDelete
  5. Anjan,

    Speaking for myself here are a few reasons (not an all inclusive list) why I have chosen Wicket:

    1. Wicket reduces the impedance mismatch between Java and HTTP. I haven't used JSP/JSF in a long while but I don't recall it having this feature. Please feel free to correct me if I am wrong. When used judiciously this can greatly reduce the complexity of web applications.

    2. I find that creating a Wicket web page is very simple. It is very similar to how I would use Swing to create a user interface in a Java SE application. This enables me to be very productive.

    3. Wicket is a true MVC - a proven best practice - based framework. The MVC design pattern provides for a separation of concerns between views and model as well as controllers. Wicket's implementation is in my opinion very good. Being able to separate concerns by view and model is very important to me as applications grow both in size and in complexity.

    4. Wicket greatly reduces the need for XML based configuration. I hate XML configuration files and I really hate debugging them LOL.

    5. Wicket makes it quite easy for me to create my own custom components that are fully self contained and which can contribute their own resources and markup to a web page. This is very important to me as I often encapsulate domain specific requirements and rules within components.

    6. Wicket makes it so easy for me to create Ajax enabled web pages and components. Wicket Ajax behaviors makes it easy to add Ajax to just about anything.

    7. Wicket's strict separation of HTML and code makes it easy to share markup with web site artists and graphic designers.

    8. Besides all of the above and not to detract from anything that I have already said -- Wicket just feels right to me!

    If you haven't already please read Wicket In Action by Matijn Dashorst and Eelco Hillenius and which is published by Manning press. The book goes into great detail on everything I touched upon here plus a whole lot more.

    Jeff

    ReplyDelete
  6. Hi Jeff,

    Thanks for outlining these points. However, i have something to say for each of them:

    1. JSF addresses exactly that. In JSF, the 'state' between requests is seamlessly maintained as part of the state of the UI components being used and/or managed beans without the coder having to worry about how HTTP works.

    2. JSF achieves exactly that too, viz. the ability to use components to build working web interfaces just as one would while building a swing application.

    3. In JSF, the view, model, and controller are separate.

    4. In JSF, i must admit, there used to be some XML involved, such as for registering managed beans. But even this requirement is somewhat reduced (if not completely removed, i think) with Servlet 3.0, whereby managed bean declarations can be done using @ annotations right inside the bean class declaration.

    5. The JSF reference implementation provides a set of basic components for rendering the most common UI elements, but the framework is open for and *encourages* developing custom components that implement specific behavior suited to a domain/application. The framework is quite flexible and documented well enough for doing this: http://java.sun.com/javaee/5/docs/tutorial/doc/bnavg.html.
    Also, there are various open-source libraries available around the web that provide pre-built JSF components for doing various stuff, e.g. Apache MyFaces Trinidad, ICEFaces, RichFaces, Facelets, PureJSF, and licensed ones such as Oracle ADF Faces Rich Client.

    6. Most of the libraries i mentioned in point#5 have pre-built support for AJAX behavior, which removes the user having to do any handcoding to implement it. JavaEE 6 (with JSF 2.0), AFAIK, has built-in support for AJAX behavior.

    Given the above, i kind of feel a wheel is being reinvented with Wicket :)

    I'd strongly suggest having a look once at the sun.com JavaEE Tutorial chapter on JSF: (JavaEE 5: http://java.sun.com/javaee/5/docs/tutorial/doc/bnaph.html, Java EE 6: http://java.sun.com/javaee/6/docs/tutorial/doc/bnaph.html). Lot of the above points would be immediately clear.

    Regards
    Anjan.

    ReplyDelete
  7. Anjan,

    I am quite familiar with Java EE. However, readers might believe that you are suggesting that Java EE is exclusive to JSF. It isn't. I and many Wicket developers routinely use Wicket in an EE container. I use Wicket and Glassfish extensively.

    You aren't also suggesting that JSF doesn't allow you to mix markup and code are you? That would be ridiculous if you were. This contradicts your point #3.

    As per your comment, "i kind of feel a wheel is being reinvented with Wicket :)" one can say that about many technologies, including JSF, asp dot net, asp, jsp, java, C++, c, cobol, fortran, etc, etc.

    I suggest that you re-read my point #8.

    Jeff

    ReplyDelete
  8. Jeff,

    There's no denying that Wicket is "as JavaEE" as JSF. All i'm trying to say here is, with all the points we discussed, i don't see why one would prefer Wicket *over* existing frameworks that provide the same functionality, such as JSF. A framework that is not part of the JavaEE standard would be useful only if it has something to offer *over* existing ones, which i don't see in the case of Wicket.

    Now if one has already developed an application in Wicket, and now simply feels comfortable with it (your point#8), then so be it, and i see no harm in continuing with that.

    However, for people who have not seen a component-driven web framework for JavaEE (to whom your post is probably intended, as i infer from the first few paragraphs), given a choice between Wicket and an existing standard that provides similar functionality, i don't see a compelling reason why they shouldn't to go with the latter.

    As for point #3, it seems my comment got turned on its head :( I did not say that one *can't* write a messy JSF application with complicated EL expressions if not the entire business logic right inside the JSP (the markup) if one wanted. No one stops anyone from doing such a sin. But:
    (i) the default JSF RI makes it hard to do so, because one cannot write java code inside scriplets in the JSP and expect it to work along with the JSF lifecycle. The recommendation is to write simple EL expressions bound to bean properties OR simple expressions bound to the *components*.
    (ii) That was just the default JSF RI. JSF's view construction layer is completely open, and one doesn't need to necessarily use JSP's. Facelets are another common way of declaring the view structure. So if you really want, one can even design a Wicket-like view construction layer (i.e. make the HTML represent the view document, with ID markers on relevant elements, and have code that generically creates the whole component tree by traversing the document).

    About reinventing the wheel: JSF, asp dot net, asp, jsp, java, C++, c, cobol, fortran, etc.. you can't just say it about all these. Most of them have/had their own merits and application areas, and one can't really replace one with another. But yes, take just java vs j++ vs c#, that's the kind of redundancy i was talking about.

    Regards
    Anjan.

    ReplyDelete
  9. Anjan,

    Most of my readers have JSF in their backgrounds. They've just come to the 'end of the road' with it so to speak. The metaphor will begin to make sense as you read further *:0)

    If standards mean that much to you then by all means, go with JSF as your chosen platform for delivering Web applications. It isn't my job or anyone's for that matter to convince you otherwise.

    There are many of us though who don't put that much importance in JSF being the 'standard'. And thank heavens for those of us that don't because there never would be any advances in technology if everyone just went along with the same old same old status quo.

    [Here's where that metaphor kicks in...]
    JSF reminds me of an old Harley motorcycle that I used to own. Yeah, it _might_ have gotten me to my destination but I had to take a mechanic's arsenal of tools with me on every trip. Then one day I was walking by a Yamaha dealership and ... Well, needless to say I sold that Harely and never looked back.

    My motorcycling days are long gone but so are the days of doing things the same old way just because someone says they are standards. When a better path shows itself I want to travel down that road.

    Jeff

    ReplyDelete
  10. I can now understand the sentiment, which you nicely describe with the metaphor. But the reasons behind it are still not quite clear, apart from the feel-good factor.

    It just seems to me pretty easy to exactly pinpoint out what's *good* in Wicket, but not really what makes Wicket *better* than a similar existing framework.

    Anyhow, good luck with taking the new wheel forward. May the best machine win.

    - Anjan.

    ReplyDelete
  11. I chose wicket over JSF after having researched the two approaches. It seemed to me that Wicket would allow me to produce more organized code much more *easily* than JSF would. In practice, I am extremely happy with Wicket. In fact after reading through the exchange on this page, I went back to look at JSF to see if I would revise my opinion at all. I remain convinced that Wicket was and still is the best choice for me. And, nota bene, I chose Wicket from scratch without prior experience (or, for that matter, prejudices).

    ReplyDelete
  12. Wicket is better than JSF and I know why - it does not build on shaky JSP foundation.

    The following "HybridJava" technology suggest a modern alternative to JSP as such:

    http://www.theserverside.com/news/thread.tss?thread_id=54866#320116

    ReplyDelete
  13. @Alex: It is a myth that "JSF is built on top of a shaky JSP foundation" so it cannot be a valid reason. It's only the default RI of JSF 1.x that uses JSP for view-tree building. That stops no-one from using any other custom technology (even something like Wicket) for building the view-tree. And in JSF2.0, *there is no JSP* in the RI, the view-tree building is done using Facelets.

    ReplyDelete
  14. IMHO we need to have some criteria to choose the right framework, we should see what one needs to achieve using a framework there are many things to be considered when choosing a good framework.

    some of the key things as a developer or from managers point of view are as below.

    1.Code should be manageable. JSF is difficult when project is big and managed by 10+ developers from different skill sets.
    wicket is better as it is done in java only.

    2.Clear separation of concerns.
    JSF (developer has to do design and do programming for dynamic stuff)
    Wicket: Designer and java developer can have their own work done in better way.

    3.Should be test driven-test automation and container independent.
    JSF: Cant
    Wicket: Easy.
    4.reduce development cycle-in build support (Ajax,security,components).
    JSF: Supports
    Wicket: Supports, but it can be easily tested which is advantage over JSF.

    5.Less configuration
    JSF:Messy
    Wicket:None.

    4.Scalable
    JSF: Not bad
    Wicket: Better.

    These are few points to be taken into account,though more exits.

    ReplyDelete
  15. IMHO we need to have some criteria to choose the right framework, we should see what one needs to achieve using a framework there are many things to be considered when choosing a good framework.

    some of the key things as a developer or from managers point of view as follows.

    1.Code should be manageable. JSF is difficult when project is big and managed by 10+ developers with different skill sets.
    wicket is better as it is done in java only.

    2.Clear separation of concerns.
    JSF (developer has to do design and do programming for dynamic stuff)
    Wicket: Designer and java developer can have their own work done in better way.

    3.Should be test driven-test automation and container independent.
    JSF: Cant
    Wicket: Easy.
    4.reduce development cycle-in build support (Ajax,security,components).
    JSF: Supports
    Wicket: Supports, but it can be easily tested which is advantage over JSF.

    5.Less configuration
    JSF:Messy
    Wicket:None.

    4.Scalable
    JSF: Not bad
    Wicket: Better.

    These are few points to be taken into account,though more exits.

    ReplyDelete
  16. @Anjan: I have spent some time reading Facelets. Why do you think that is better than JSP. They have one common problem here. The problem is in the definition of component. The component in both approaches are bricks you may build from. But what you get is a View of a page. Not MVC page, but only V. In this Wicket digs much deeper. But HybridJava provides a much more elegant solution. See "5 principles of HybridJava component model" on HybridJava site.

    ReplyDelete
  17. @Anjan: I totally agree with Jeff. I have used various frameworks from Struts to Wicket. Wicket is one framework which has impressed me in terms of features and ease of development. JSF is a mess of tags and heavy.

    Refer to the post below:

    http://ptrthomas.wordpress.com/2009/01/14/seam-jsf-vs-wicket-performance-comparison/

    @Jeff: One thing is for sure that Wicket is more suitable for a person who has come from a Swing development background and has strong OO concepts. Things can go wrong if the best practices and basics of Wicket are not understood in depth specially the session management in Wicket.

    Shirish

    ReplyDelete

Note: Only a member of this blog may post a comment.

About Me

My photo
New York, NY, United States
Software Developer