This post is meant to document our experience developing a demanding UI for a large enterprise application using GWT and Errai as our client technologies.
We began looking at GWT over 4 years ago. Immediately we were attracted by its promise to harmonize server and client development into a single environment (Java). It is interesting to me how controversial this approach has proven to be. We have been big believers in what GWT represents, and depending on the type of project you are embarking on, I would definitely recommend its use.
Consumer vs. Enterprise
There is a world of difference between building a consumer-facing application and an enterprise application. As a general rule, consumer applications (in today’s world) have relatively narrow user experiences, often comprising less than 10 screens (think Twitter, Pintrest, Instagram and even Facebook) with often millions of low-value users. Countless hours are spent refining the user experience, but from a technical level, the UI is pretty contained. The real challenges lie in the backend infrastructure and scale.
Enterprise applications are a completely different animal. Users are often charged significant amounts of money to use the application (upwards of $100/month), and the number of interaction screens will often run into the hundreds. Our new application has over 500 screens, and this number will continue to grow. It was our intention to develop an enterprise application that would “blow people away” when they first saw it. The user experience was critical, and providing a top notch, consistent interface across so many screens became a top priority and challenge.
Key to Success – Functionality
We set out a number of very ambitious goals for our user environment. Coming from a client-server application, we wanted our first “web version” to take all of the positive things from that environment, and combine it with all of the strengths of a web environment. This meant building our own desktop environment, including a window manager, universal keystroke management and a series of widgets to manage the consistent presentation of information. GWT enabled us to develop a very complex desktop library, and do so easily. Because we were able to write it in Java, we got all the benefits of the Java Environment: IDE auto-completion, refactoring, and type safety. This meant that even with a minimal amount of external documentation and testing, we were able to get a desktop library usable and stable quite quickly. Versions could also be maintained and controlled via Maven.
Key to Success – Simplicity
GWT promised to minimize, if not completely erase this problem. This is no small gain, both for growing teams trying to accomplish big things and large teams hoping to maintain what they’ve built. By unifying the environment around one technology (Java), it meant that a huge amount of the client-specific challenges could be eliminated, or at least isolated from the majority of development.
Key to Success – Efficiency
This is the one where GWT skeptics will probably get their backs up. One of the complaints I see most often is that GWT is not efficient – you have to write too much code, and it takes too long. One of the challenges that GWT has had I believe is of (marketing) messaging and communication as to what it is and how it is best used. I believe GWT (and Errai) suffer from the reverse problems of many frameworks. Many frameworks excel in the Hello World examples, but as things get more complicated, they start to fall apart. With GWT (and Errai) there is a pretty steep learning curve to really start to architect applications. However, as you begin to get your feet wet and the application grows in complexity, this is where the technologies really begin to shine.
One of GWT’s secret sauces is Deferred Binding, and generators (http://www.gwtproject.org/doc/latest/DevGuideCodingBasicsDeferred.html). This feature allows you to generate code, and once mastered, is an incredible asset to reducing boilerplate and building a solid, consistent framework. In fact, it is the foundation of most features of GWT (UiBinder/Editor), and also libraries such as Errai. However, it is only after using and understanding GWT that this feature can really be exploited.
Problems with GWT
Google was developing the functionality and releasing versions, but was ultimately working to support internal projects. It was as if it didn’t really care about external adoption (this is perhaps unfair, but it represents an impression more than reality. For a comparison, take a look at the Dart Language website/IDE). The community was left to its own to develop frameworks, best practices, and much of the higher functionality required to make it a more easily adoptable framework. I always wonder what would have been if Google had invested a little more in GWT as a (free) product, as opposed to an opensource project.
When I stumbled upon Errai, I was re-introduced to JEE. We had previously explored a variety of backend frameworks, including Spring and most recently Guice. I was instantly amazed and attracted to the simplicity and elegance of JEE – in particular the CDI API. Once I had my JBoss AS 7 environment set up, I was incredibly pleased with how neatly everything just seemed to “work” – REST, Persistence/Transactions, CDI, and how little configuration was required. It almost didn’t seem possible.
Errai Message Bus
Errai RPC is a much more elegant service oriented communication protocol. In stock GWT, three classes are needed to implement a service (two interfaces, almost the same, but one asynchronous, along with a server Implementation). The server implementation is a servlet, so typically some more work is needed. In Errai, a service is created with an interface and implementation. No special asynchronous interface is required. Using the magic of Deferred Binding and Errai CDI, an Errai service caller is injected on the client and is able to make the asynchronous call using the synchronous service. On the server side, the service need only be annotated with an Errai @Service annotation. Errai then handles all of the routing. This made setting up new services completely painless and easy. On top of that, using the same interface and calling mechanism, Errai can talk directly to existing REST endpoints.
Errai CDI Events
When looking back into JEE, I really was taken by the simplicity and effectiveness of CDI Events (if you are unfamiliar with CDI events, you can learn about them here: http://docs.oracle.com/javaee/6/tutorial/doc/gkhic.html. It takes about 2 minutes, that’s how easy they are to understand and use). When I saw what I could do with Errai+CDI, I was truly blown away. CDI Events represent a way of broadcasting server-side events to a number of listening clients (and vice-versa – client’s can broadcast events back to a listening server). This is a feature that has become crucial to our desktop environment. One of the features of our interface, is that screens are loaded and kept in memory in the browser. This raises the issue of stale data. With a single annotation, we are able to set up listeners for events in the browser.
Errai Dependency Injection
Previously, we had architected our application using Google Guice on the backend and Gin (a Guice GWT port) in the browser. At first we were quite happy with Guice, and found that it was not easy to get a direct replica of the server-side functionality. Furthermore, the level of configuration that was required made it overall more complicated to use. JEE CDI, on the other hand, felt somewhat limited coming from the Spring/Guice environments. However, it did not take long to accept its limitations, and I can honestly say we have had no issues with functionality using server-side CDI, and have grown to appreciate the lack of configuration that is required to make it hum.
Errai UI is Errai’s replacement for GWT’s own UiBinder. It is a very clever take, and in keeping with the framework, relies heavily on tried and true standards. Unlike UiBinder, which uses an XML template with its own namespaces to define layouts, ErraiUI uses strict HTML. This makes working with designers much (much!) easier, as they can define screens, update screens, etc, that can just be ‘dropped’ into your java project.
Another nice advantage is that one HTML file can actually support multiple java classes (each java component can reference which dom Id represents the the root of the component). This means the designer can have a single HTML page that contains multiple widgets, screens – another big win.
Finally, another thing that is nice about ErraiUI is that is builds on Errai’s dependency injection.
Using GWT’s UiBinder, you typically need to declare an interface, and then use deferred binding to create it:
Then in your code, you would call uiBinder.createAndBindUi(this) to actually make the widget. This actually gets tedious after a while (even using the GWT Eclipse plugin, which is not ideal).
Errai Data Binding
Data Binding is another relatively new entrant into the Errai Framework. Like its name suggests, it enables the binding of editing widgets to POJOs. This is a loose replacement of the stock GWT Editor framework. The GWT Editing framework was a good attempt at this functionality, but falls short on many levels, and we have found it very hard to work with, especially using an MVP architecture. Unlike the GWT Editor, Errai Databinding keeps the backing bean in sync with the contents of the editors. It also has useful tools like global property listeners. Lastly, combined with Errai CDI, it is incredibly easy to set up and use.
We have been extremely happy with our experience building a large enterprise application with GWT and Errai. Both GWT and Errai continue to evolve and improve, but they already represent invaluable tools to enable development teams to produce high quality software and do so productively.
I recently came across a talk on Progress Enhancement from ([UPDATE: former]) Yahoo Engineer Nicholas Zakas (hat tip @tbroyer). I spend a lot of time mulling over UX issues and it always makes me feel good when I come across a “pro” who validates many of the conclusions I’ve come to over the years. I thought I would take the time to share our experience with progressive enhancement in designing our application.
Writing browser-based applications for the enterprise market presents different constraints than creating websites for your average consumer, so understand the perspective these comments come from.
The crux of the talk is that the experience of our site/application does not have to be the same across all browsers/screens. This may not seem controversial, but I have worked in several organizations where designing for the lowest common denominator was required – to the point of absurdity. Indeed the tide appears to be turning across the web (I recently noticed that Asana will not even run in IE (IE!) without the ChromeFrame plugin – try picturing that 3 years ago).
When setting out to design the interface for our new supply chain package, I wanted to do something that was cool and innovative (people would sit up and take notice), yet not something that was so foreign or complex that the user would feel lost. My main challenge, as I saw it was that screen sizes (and in particular widths) vary incredibly across people’s desktop, and that the typically response to this problem is….design for the lowest common denominator (now considered 1024×768). This seemed an insufficient response. More and more users have beautiful HD screens (1920×1080) – why should they not be rewarded (or worse – suffer) because others (in our case ‘power’ users) wont invest the $200 required to get a new monitor (funny side note – when we went into alpha testing with an existing client, it turned out that a few of the users were in fact still using 1024×768 resolutions)
GWT’s RequestFactory library is an extremely powerful alternative to the standard GWT-RPC for data-object based communication between client and server. GWT’s RequestFactory page explains in detail how to get started, but I will try and summarize and expound upon their rather limited (for practical purposes) explanation. We have encountered several problems in rolling out our implementation with RequestFactory, so if we can share some of what we’ve learned, along with our wish list (any Googlers out there!?), hopefully you can get some benefit.
Like any enterprise application, ours is heavily dependent on forms. Some of these forms are pretty simple, while some can get very complex, both in terms of size, and complexity. While undertaking our redesign, we spent a lot of time thinking about our forms (we have several hundred), and how we could make them easier for the user.
When trying to generalize form design, I think it is important to differentiate between “temporary users” – users who will fill a form once or twice, and “power” users – users who will use an application 8-hours a day, 5 days a week. For temporary users, simplicity is paramount, as they are unfamiliar with what is being asked of them. For power users, the equation is a little different:
- Power users will be working with dozens (hundreds) of forms within an application. Conventions can be introduced to enable productivity in the design of the forms. This can’t be done for a one-time user.
- Scrolling is inefficient for fixed-size forms (forms that don’t grow with the size of data – i.e. lists)
I recently came across this article Why Users Fill Out Forms Faster with Top Aligned Labels, and found it interesting, although I don’t think its thesis applies universally, and certainly not in the business application case.
The difference is clear. Top aligned labels are easier on the eyes, and make long forms simple and easy to fill out. Even though they may make forms look longer, when the user actually uses the form they’llnotice a dramatic difference in the time and effort it takes to complete the form. If users are able to have a better experience with forms, then using top aligned labels is well worth it.
We can leave aside the issue that no evidence is given for the assertion that there is a dramatic different in the time and effor it takes to complete the form. I think I intuitively agreed, and some of our first prototypes included designs with top-aligned labels. However, those prototypes never felt quite right, and we made a design decision to avoid scrolling at almost all costs.
To make things simpler, we broke our data into chunks using wizards (on creation of a purchase order, for example) where the data breaks into natural chunks (header detail, item detail, notes), and is separated into ‘fixed size’ (header fields) and ‘data-dependant size’ (items, notes). To enhance the user experience, the operator can advance the wizard by using hot-keys (CTRL-left/CTRL-right).
We have spent a lot of time thinking about how to develop our forms in a way that could be applied consistently throughout the application. For us, the biggest challenge was finding the balance of density on a form. Because we are dealing with so much data, the temptation is to stuff as much as possible on the screen. Indeed, this was the way Client-Server applications were designed in an era of small screens, small fonts, and poor UI flexibility at the developers disposal. Consumer application tend to go the other way – large fonts, and sparse forms – to make things as simple as possible for temporary users. Hopefully we have struck the right balance. The feedback we have received so far indicates we are on the right track.
In a previous life, I had an obsession with the idea that collaboration software would (and should) replace e-mail for work-based communication. 5 years ago, I gave it a stab, but the idea was ahead of its time. While I have given up on making it myself, I am on a constant search for the ultimate collaborative tool. Much to my office’s chagrin, I have evaluated several tools over the last few years, never getting much traction. Since introducing Asana a few weeks ago, I think we may finally have some traction.
Asana was developed by Dustin Moskovitz, one of the original founds of Facebook, as a light-weight task/to-do manager for teams of people working on projects. Much like our business (supply chain), collaborative SAAS offerings seem to be offering “point” solutions – they do what they do, and if used as intended they can be quite useful, but if you try and extended them, you may find them lacking. The trick when trying to adopt a tool like Asana is to relax your work muscles and try and learn how the tool wants you to work, and not try to fight it (at least initially). While some may flinch at this notion, I tend to embrace the idea that smart people have spent a lot of time working out a collaborative methodology and there is a good chance it is better than ours (especially if ours primarily depends on email).
The premise for using Asana is that people are constantly going about doing micro-tasks (“fix this bug”, “send me this report when its ready”), and that these tasks are so numerous and fluid that using a heavier tool such as project management is not appropriate. Using email creates its own set of problems around visibility and tracking. Asana attempts to find the sweet spot of easy of use, and collaborative functionality. It allows its users to enter one liners “add field X to the table in the database”, assign it to a user, set a due date, and add a longer description, all without touching the mouse in a matter of seconds.
What I like:
- Really fast to use. Takes all of 5 seconds to add a task
- Simple feature set. Keeps workflow pretty basic.
- Rewarding. Nothing like banging out 10 completed tasks in an hour and checking them off for all to see.
- Inbox. It took a little to get used to it, but Asana allows you to indicate tasks as for today, upcoming, or later. When tasks are created, they flow into your “inbox”. I highly recommend giving a time horizon (today/upcoming/later) as they come in to keep your inbox clean. Otherwise, thing can get murky.
- Tagging. Tags are a really nice way of organizing everything. A nice bonus: Private tags. You can keep your own set of tags to organize things the way you like, without affecting others.
What I’d like to see:
- Basic dashboards. I know this is not a project management tool, but some sort of higher-level view would be very beneficial, especially to managers to see who is doing what for which projects.
- Activity streams. I’m suprised this hasn’t made it into the app at launch since its all the rage, but as of now, when you log in, it is impossible to see what has changed recently (unless I’m missing something).
- Batch Emails. It would be nice to be able to indicate how you would like to follow tasks/projects (email immediately on change, or perhaps once or twice a day, with a summary)
As you can see, my list of “wants” is pretty short. This is a pretty promising app, and given its free for groups fewer than 30, it is pretty good value too.
Check it out at https://asana.com/.
About three years ago, we began a total ground up rebuild of our global supply chain management software. This marked our third time over the past twenty years that we have rebuilt the application from the ground up. The first iteration was character based. The second was client server in a windows environment. One of the knocks on our C/S software was that the interface was not as intuitive/pretty as it could be. This presented a challenge for us both with our existing user community, and in trying to sell the application, as it did not show as well at it should have. The requirements of supply chain software are incredible, both in scope and complexity, and even though our application was capable of amazing results for our clients, the fact that it did not present well was becoming more and more of an issue for us.
So, a little bit about this blog. I have finally decided to take the plunge and get a blog going. I know I know, blogs are no longer ‘cool’ – its all about twitter, facebook, etc etc. Social media is great, but there is only so much that can be said in a tweet. As I go about my daily work, I find I still heavily rely (and enjoy) those who take the time to formulate full thoughts and share them via their blog, so I thought I would give back, and maybe help others along the way.
This blog will cover a variety of topics that I encounter in my day-to-day work getting a rebuilt enterprise software application off the ground at Blinco Systems. Mainly, I will focus on Technology and its impact on the Enterprise (and SMBs) at a high or business level, but every once in a while I may just delve a little into the nitty-gritty.
Please feel free to contact me if you have any questions, thoughts or ideas at jblinick (at sign) blinco.com.