Technical Articles by Sony Mathew, Software Architect, Prime Therapeutics, Eagan, MN


Tuesday, February 17, 2009


Comparing RIA Frameworks

Giving a Rich face-lift to an organization's websites can deliver such a superior user experience that quite possibly it can give the organization a clear edge over its competitors, but choosing the right RIA framework for your team is never an easy task. The frameworks, categories, and details presented in this article are not exhaustive by any means.

Reviewer: Sony Mathew: GWT 1.5, Laszlo 4.2, JavaScript Raw
Reviewer: Mark Ulmer: Flex 3.2

GWT 1.5 | AJAX Flex 3.2 | FLASH Laszlo 4.2 | AJAX Laszlo 4.2 | FLASH JavaScript Raw | AJAX
Platform/Technology Standard Browser
(HTML, JavaScript, AJAX).
FLASH
(Browser plug-in by Adobe)
Standard Browser
(HTML, JavaScript, AJAX).
FLASH
(Browser plug-in by Adobe)
Standard Browser
(HTML, JavaScript, AJAX).
User Experience Modest Rich
Approaching Desktop App feel
No Page refreshes, all data-access & rendering in the background.
Very Rich
Is exactly like a Desktop App
No Page refreshes, all data-access & rendering in the background.
Modest Rich
Approaching Desktop App feel
No Page refreshes, all data-access & rendering in the background.
Very Rich
Is exactly like a Desktop App
No Page refreshes, all data-access & rendering in the background.
Modest Rich
Approaching Desktop App feel
No Page refreshes, all data-access & rendering in the background.
Browser Support Relies on WWW standards. Supports all relevant browsers including IPhone & Android browsers. Incompatibility issues are minimized but still present e.g. with CSS or custom components. Supports all relevant browsers including future Android browsers but not the IPhone. Zero incompatibility issues, but unlike standards plug-ins compete for user base. Relies on WWW standards. Supports all relevant browsers including IPhone & Android browsers. Incompatibility issues are minimized but still present. Supports all relevant browsers including future Android browsers but not the IPhone. Zero incompatibility issues, but unlike standards plug-ins compete for user base. Relies on WWW standards. Can support all relevant browsers including IPhone & Android browsers. Incompatibility issues can be major unless using a 3rd party library.
UI Code Java, Compiled to JavaScript, Styled by standard CSS, Code HTML for Custom components. Some JRE not simulated e.g. BigDecimal, Calendar, DateFormat, NumberFormat but can fix. XML markup & ActionScript (Javascript with OO & static typing). Compiled to Flash SWF. Styled by custom CSS. XML markup & JavaScript, Compiled to JavaScript. Styled by custom CSS. XML markup & JavaScript, Compiled to Flash SWF. Styled by custom CSS. JavaScript & HTML DOM Manipulation. Styled by standard CSS.
Access Remote Services & Data. Invoke remote Java services and transport Java beans like RMI (Declare remote Java interfaces + Mark transported beans as Serializable + Java Servlet to process RPC requests). Can also do direct HTTP, transport XML or JSON to/from Servlet & use via their API for XPATH or JSON. Configure access to any Java bean & transport beans as ActionScript objects. Can also do HTTP or SOAP, transport XML to/from Servlet & & use via easy XPATH bindings to views. Can do HTTP or SOAP, transport XML to/from Servlet & use via easy XPATH bindings to views. Can also configure RPC directly to a Java bean & access transported beans as JavaScript objects. Can do HTTP or SOAP, transport XML to/from Servlet & use via easy XPATH bindings to views. Can also configure RPC directly to a Java bean & access transported beans as JavaScript objects. Can do HTTP, transport XML or JSON to/from Servlet & use via XPATH or JavaScript objects.
Code Complexity Management Java files, Compile-time type safety, Organize into Class/Object hierarchies, Packages, Modules. XML Files & ActionScript files, Compile-time type safety, Organize into Class/Object hierarchies, Packages, Modules & Libraries. XML Files, Organize into Object/Prototype hierarchies & Libraries. XML Files, Organize into Object/Prototype hierarchies & Libraries. JavaScript Files, Organize into Object/Prototype hierarchies.
Tool Support / Eclipse Integration Use all Java Tools, Free command-line Compile/Build or custom Eclipse plugin for Compile/Build. Run/Debug from Eclipse like regular Java. Navigate to API docs from Java Editor. Use all XML Tools, Free command-line Compile/Build or Adobe Eclipse plugin ($250) for Compile/Build & Run/Debug & good graphical WYSIWYG editor. Navigate to API docs from XML or ActionScript Editor via Eclipse plugin. Use all XML Tools, DTD/Schema not kept current & not usable if creating new object tags. Run from Browser and use interactive Debug console in Browser (console had some issues with IE). Switch between DHTML & FLASH 8 & 9. View separate online docs in browser - no navigation shortcut. Use all XML Tools, DTD/Schema not kept current & not usable if creating new object tags. Run from Browser and use interactive Debug console in Browser. Switch between DHTML & FLASH 8 & 9. View separate online docs in browser - no navigation shortcut. Edit with a Text or JavaScript Editor. Run from Browser - use FireBug and similar tools to debug. View separate online docs in browser - no navigation shortcut.
Refactoring & Code-Completion Support All Java Refactoring & Code Completion. Eclipse plugin provides standard refactoring operations (rename, move, etc.) & Code-Completion. Some XML Element/Attribute Completion but DTD/Schema not kept current & not usable if creating new object tags Some XML Element/Attribute Completion but DTD/Schema not kept current & not usable if creating new object tags None.
JEE Integration Lives in any WAR project. Generates JS files for inclusion in WAR. Lives in any WAR project. Generates SWF files for inclusion in WAR or compile just-in-time at runtime. Lives in any WAR project. Generates JS files for inclusion in WAR or compile just-in-time at runtime. Many jars (some unnecessary). Lives in any WAR project. Generates SWF files for inclusion in WAR or compile just-in-time at runtime. Many jars (some unnecessary). Lives in any WAR project. Include & Edit JS files in your WAR.
Migration Can integrate with existing Web-Apps as new pages or part of a page, Allows deep links into workflows. Can reuse existing beans & can remote access to existing Controls & Services including sharing of session data. Can integrate with existing Web-Apps as new pages only, Allows deep links into workflows. Can reuse existing beans & can remote access to existing Controls & Services including sharing of session data. Can integrate with existing Web-Apps as new pages only, Allows deep links into workflows. Can reuse existing beans & can remote access to existing Controls & Services including sharing of session data. Can integrate with existing Web-Apps as new pages only, Allows deep links into workflows. Can reuse existing beans & can remote access to existing Controls & Services including sharing of session data. Can integrate with existing Web-Apps as new pages or part of a page, Allows deep links into workflows. Can reuse existing beans (with explicit JSON conversion) & can remote access to existing Controls & Services including sharing of session data.
Performance Fast download time to Browser, Fast startup time, Modest Browser Responsiveness (All relative to size of App). Can modularize to decrease download/startup times. Low bandwidth usage compared to traditional web apps. Modest download time to Browser, Modest startup time, Fast Browser Responsiveness (All relative to size of App). Can modularize to decrease download/startup times. Low bandwidth usage compared to traditional web apps. Modest download time to Browser, Modest startup time, Modest Browser Responsiveness (All relative to size of App). Can modularize to decrease download/startup times. Low bandwidth usage compared to traditional web apps. Modest download time to Browser, Modest startup time, Fast Browser Responsiveness (All relative to size of App). Can modularize to decrease download/startup times. Low bandwidth usage compared to traditional web apps. Modest download time to Browser, Modest startup time, Modest Browser Responsiveness (All relative to size of App). Can modularize to decrease download/startup times. Low bandwidth usage compared to traditional web apps.
Static-Content (Externally Managed) Can mixin HTML & CSS as-is or modified. Can parse XML content or plain-text. Can parse XML content or plain-text. Can mixin basic HTML text (Not CSS) as-is. Can parse XML content or plain-text. Can mixin basic HTML text (Not CSS) as-is. Can parse XML content or plain-text. Can mixin basic HTML text (Not CSS) as-is. Can mixin HTML & CSS as-is or modified. Can parse XML content or plain-text.
Testing Supports Unit Tests. There are various Record/Playback/Scripted tools e.g. Selenium. Load Testing ?? (Script with HtmlUnit?) Adobe provides FlexUnit for unit testing. There are various Record/Playback/Scripted tools: FlexMonkey, FlashSelenium, Mercury QuickTest. Load Testing ?? There are various Record/Playback/Scripted tools e.g. Selenium. Load Testing ?? (Script with HtmlUnit?) There are various Record/Playback/Scripted tools: FlexMonkey, FlashSelenium, Mercury QuickTest. Load Testing ?? There are various Record/Playback/Scripted tools e.g. Selenium. Load Testing ?? (Script with HtmlUnit?)
Accessibility Supports the W3C Initiative for Accessibility for Rich Internet Apps (WAI-RIA). Supports Microsoft Active Accessibility (MSAA) for Internet Explorer. None (custom build?) Supports Microsoft Active Accessibility (MSAA) for Internet Explorer. None (custom build?)
Printing Can print as with HTML pages. Can print with additional page setup. Can print as with HTML pages. Can print with additional page setup. Can print as with HTML pages.
Search Engine Optimization Not directly compatible (embed host pages with search terms). Not directly compatible (embed host pages with search terms). Not directly compatible (embed host pages with search terms). Not directly compatible (embed host pages with search terms). Not directly compatible (embed host pages with search terms).

Issues with GWT

Google Web Toolkit (GWT) is an AJAX based RIA framework that promises to enrich your Java/JEE Web Applications with a Rich user experience. It also promises to ease error-prone JavaScript & HTML development by abstracting it under the safety of a compile-time language like Java. GWT is a good framework overall and delivers on most of its promises -but- a few short-comings are to be noted.

Reviewer: Sony Mathew, GWT version 1.5

  1. Great Tool support but...

    1. Being in Java all Java IDE tool support is available at your fingertips.
    2. Comes with a GWT Browser for immediate edit feedback but can be slow.
    3. Debugging of client-side and server-side seamless in Eclipse.
    4. Had to custom build: Eclipse plugin for compilation & workspace Ant tasks.
      • May not need as better plugins come out.
  2. UI Design in Java maybe cumbersome.

    1. No Graphical designer (GWT Designer exists, haven't tried, its for pay & don't expect much).
    2. Fix: Complex layouts can be easily abstracted into components and reused.
    3. Fix: Complex HTML layouts and semi-static HTML snippets can be easily abstracted to Static-Content and reassembled dynamically.
    4. Fix: Fluent interfaces like AxisPanel can be easily created to alleviate complex layouts
    5. Fix: Can purchase/obtain 3rd party rich components.
  3. Compilation takes a while.

    1. Don’t need to compile very often during dev.
    2. Compile initially and when making changes to RPC transported beans.
    3. View UI edits via GWT provided browser for changes.
  4. Browser inconsistencies abstracted well but...

    1. CSS inconsistencies still remain, All Widgets are CSS driven.
    2. HTML/JavaScript inconsistencies abstracted well but custom components will require some hand-coding of HTML & JavaScript.
  5. Cannot style all areas of all Widgets.

    • E.g. parts of TabPanel.
  6. Java/JRE Emulation limitations

    Requires that classes be scrubbed of following unsupported (non-compilable) references:
    1. 3rd Party classes:
      • e.g. org.apache.commons.*, org.hibernate.* etc.
      • Fix: Eliminate references.
      • Fix: Add source (.java) to classpath.
      • Fix: Use your own custom equivalents (e.g. custom ToStringBuilder).
    2. BigDecimal:
      • Client-side BigDecimal math not supported because it is not performant.
      • Fix: Can use 3rd party 'gwt-math.jar'.
      • Fix: Redesign beans to use Money, inject appropriate client/server side MoneyCalc.
    3. List.subList():
      • Fix: Use an explicit for-loop to create a new list.
    4. Object.clone():
      • Fix: Use a Copy Constructor and set fields individually.
    5. java.util.Calendar, java.text.DateFormat (and subclasses) :
      • Fix: Use deprecated java.util.Date constructors and methods.
      • Fix: Redesign beans to use java.util.Date, inject appropriate client/server side Formatters.
    6. java.text.NumberFormat and java.text.*:
      • Fix: Use GWT provided classes - not optimal unless on client side.
      • Fix: Redesign beans, inject appropriate client/server side Formatters.
    7. Misc RPC Serializing issues:
      • Doesn't serialize final fields.
      • HashMap: Make sure contents are serializable.
      • Old Style Enums require no-arg constructor and non-final fields.
    8. GWT Unit tests:
      • If present in same package can cause compile errors unless you scrub the tests: Including placing junit source on classpath.
      • Note: having different source folders will NOT help if .class files are compiled to same output location.
  7. Scrub Hibernate loaded beans of non-compilable references.

    1. Only if loaded beans reference Hibernate classes such as HashSet, Session etc.
    2. Only an issue for lazy-loaded associations & collections (verified).
      • Hibernate beans with no lazy assocs were readily serialized.
    3. Fix: Hibernate.initialize() on all objects
      • May not be sufficient - verify.
    4. Fix: Deep Copy beans:
      1. Manual Copy Constructors on beans.
      2. Use automated reflection based copy (including for collections).
  8. Can use server-side classes on client-side but...

    1. Requires a “gwt.xml” file in referenced Java package (2 lines).
    2. May require scrubbing of non-compilable references.
    3. May require scrubbing of Hibernate loaded beans for RPC serialization

Wednesday, December 3, 2008


Fluent DSL for Rich-UI

User Interface (UI) Layouts are generally defined using declarative forms such as HTML or XML. One of the primary reasons for this is to separate roles of UI designers and programmers - whether they are separate individuals or the same person. However, this separation is going to reach its practical limits as user experience requirements get richer and more demanding - what I mean is - an XML or HTML template is just NOT going to be a valid representation of the view that the user sees because at the end of the day its just a static view. A richer experience by definition means the view is changing constantly with each user action - sometimes drastically - this means the code behind the template will become the center of focus as it re-shapes the view in response to user actions. As for XML or HTML templates - well they can continue to have a place subordinate to the UI code, loaded on demand perhaps for small fixed layout sections and like its cousin "the image" banished to the static content-managed realm. Additionally, code close to the UI will be managing more data, state transitions and controller logic for quicker user responses. People who demand a "staticky" template-first approach for UI design will end up with an increasingly complex soup of code mixed inside an increasingly irrelevant and inaccurate template - creating something that neither the UI designers nor programmers can consume easily with their minds or their tools. It will become more practical in the future for programmers to develop the UI using a programming language from a set of mock-ups created by the UI designers - to fully deliver the dynamic user experience desired. However, building UI in programming languages can be verbose and cumbersome with little clarity and virtually no visual clues to the layout structure in the code. This needs to be fixed - and it can be fixed by heavily leveraging Object-Oriented features - in fact with the right approach OO languages like Java can provide a truly great experience for laying out complex UI for Rich Internet Apps (RIA) (not to mention for Desktop Apps or even today's old-fashioned static HTML generating web apps). UI Building in an OO language can be made fluent and succinct such that it can out-do any equivalent HTML/XML format in simplicity, clarity and functionality. Unlike external DSLs that exist today - I would prefer a DSL internal to my native programming language for building my UI. A DSL internal to your native language simplifies the transition you undoubtedly must make between your UI and its supporting data models, controls and services written in your native language - not to mention being able to use your favorite language tools like code-refactoring. Now I am not suggesting that all UI frameworks in the future should support a single Fluent API (or be written only in Java) but if enough DSLs start looking similar - a standard should be considered for your favorite programming language and adopted by the web frameworks supporting that language.
The terms Fluent and DSL are in reference to Martin Fowler's writings. I won't go into detail regarding them. Checkout Martin Fowler's entries DomainSpecificLanguage (DSL) and FluentInterface.

AxisPanel: An example

Lets look at an example of a fluent layout panel I created in Java called AxisPanel. I created this primarily for GWT but I've also created a sample panel for Swing, and conceivably such a Fluent API could also be created for generating old-fashioned static HTML on the server-side (imagine NOT having to deal with untyped ${expression} anymore). The AxisPanel API attempts to follow the elegant principle of self-similarity (a property of Fractals) such that complex layouts are created with a few simple constructs applied recursively. AxisPanel lays your widgets out in the X axis (horizontal) or Y axis (vertical), you can nest as deep as you like and set properties for any panel at any depth, and the important part is: you can modify your layout at any nesting depth simply by adding/removing x or y panels - you don't need to create new wrapper panels, find suitable variable names for each of them, or refactor insertion points of old panels every-time you change your mind as to where widgets are positioned. This combination of horizontal and vertical layouts along with the fluent interface creates a very effective and powerful DSL in Java for laying out UI of almost any complexity. Here is an example of using AxisPanel to emulate a simple Border Layout i.e. laying out widgets in a North, South, East and West fashion.
AxisPanel p = new AxisPanel()
.y().width("100%")
    .x(myNorthContentPanel).css("north").q()
    .x().width("100%")
        .y(myWestContentPanel).css("west").q()
        .y(myCenterContentPanel).css("center")
            .width("100%").align(0,0).q()
        .y(myEastContentPanel).css("east")
            .width("100%").align(1,0).q()
        .q()
    .x(mySouthContentPanel).css("south").q()
    .q();
Where: x(...) - Add widgets horizontally. y(...) - Add widgets vertically. q() - Quit building the current panel and revert to building the parent panel. css(..), width(..), etc. - various properties that can be set on any panel. Note: The various content panels (e.g. myNorthContentPanel) could have been created in-line recursively as well, but to emphasize the Border Layout they are shown as created earlier (perhaps as other AxisPanels).

AxisPanel: Another example

The following example lays out a series of search options on the top half of the page followed by a dynamic bottom section that changes based on the search performed i.e. results section. The results section has a results table and a cart - and users can move items between the results and the cart real-time. This example shows the layout only - the interactive widgets like buttons, links, text-boxes along with their action listeners were created prior to their layout (as I layout and find I need a button or a text-box, I create them just above the layout or in another dedicated method).
AxisPanel p = new AxisPanel()
.y().css("search").border(1)
    .y().css("options").space(5)
        .x("Search Options").css("header").space(5).q()
        .x(searchByNameOption,searchByNameBox).css("byName").space(5)
            .x(alphaLinks).css("alpha-links").space(5).q()
            .q()
        .x(searchTop10Option, searchTop10Box).css("top10").space(5).q()
        .x(searchButton).space(5).q()
        .q()
    .y().css("results").width("100%").space(5)
        .y().css("info").space(5)
            .x("Search Results").css("header").q()
            .x("Click Cart+ to move items to cart")
                .css("howto").q()
            .q()
        .x().space(20).width("80%").align(0,0)
            .y().css("detail")
                .x("Your Results").css("header").q()
                .x(searchResultsTable).css("table").border(1).q()
                .x(pagePrevLink, new Label("page"), pageNextLink)
                    .space(5).width("100%").align(0,0).q()
                .q()
            .x(new Image("/path/to/arrow/image")).q()
            .y().css("cart")
                .x("Your Cart").css("header").q()
                .x(itemCartTable).css("table").border(1).q()
                .x(itemCartRemoveAllLink).space(5).width("100%")
                    .align(0,0).q()
                .q()
            .q()
        .x(checkOutButton).width("80%").q()
        .q()
    .q();
Here is the result of the above sample layout:

In conclusion:

Hopefully, the AxisPanel example demonstrates that you can create a Fluent Object-Oriented DSL within your native language that is simpler yet more powerful than its declarative XML/HTML cousins for coding Rich Internet Apps (RIA) (in addition to Desktop Apps or even old-fashioned static HTML generating apps). Without a Fluent API, complex layouts in your native language can be verbose with unclear layout structures and cumbersome modifications. AxisPanel is a good start but I would like to see more Fluent APIs in Java and other OO languages coming out of the wood-work and supported by more web-frameworks directly. See sample AxisPanel code: http://code.google.com/p/xsonymathew/wiki/AxisPanel