Posts Tagged ui

GXT 2.0 final fails

It’s been four months since I first wrote about my experience starting to use GXT and freshly diving into a 2.0-M1 upgrade. Since then my project has upgraded to 2.0-M2, 2.0-M3, RC1, RC2, and finally 2.0 GA, with even a couple svn trunk builds in between for good measure. In fact after M2 I stopped writing about because it was just more of the same messy, things-don’t-work-like-they-used-to-or-at-all-and-worse-are-different-in-every-browser shananegians every time. I kept hoping that our experience was simply an artifact of so many changes in 2.0, their dev team being clearly overwhelmed, and would still converge on some form of synergistic vision by the final release. I was sadly mistaken.

GXT fails, and this will be the last time I bother to comment on it unless it spontaneously improves before I stop using/thinking about it entirely. My project is removing it where possible, minimizing its use when necessary, and hoping to leave it in the dust by way of GWT 2.0 and incubator advancements over time.

Some examples of the types of issues still present (albeit changing flavors regularly) in GXT 2.0 final are:

  • Component and/or layouts only render correctly – or at all – when wrapped in a specific type of parent component that otherwise has no bearing on its functionality
  • Many components, including the really visible ones like Grid, render differently in each browser, or sometimes not at all (especially in Chrome)
  • Components behave in wildy different ways when aspects of their state such as hidden/visible or enabled/disabled are set prior to render, during render, or after render, e.g. calling hide() before something is displayed causes it to appear malformed and non-functional rather than being hidden
  • Tooltips – and popups in general – don’t display, display in random locations, refuse to hide, or render incorrectly when re-used; in fact unconstrained use of “new” keyword any time you need to display something has become a necessary anti-pattern on my team to get things to render correctly
  • Funny, but sad, breaking API changes like removing Window.close(), with explanations like “because it never worked like you’d expect it to so you never should have used it anyway”
  • Arbitrary (accidental?) functionality tweaks like changing which item is selected by default when you open a new combo box or when which actions on a check box (blur, click, etc.) actually fire the change event; these are superb at breaking UI tests
  • Heavy-handed style approaches (think programatically setting element.style from a private method) that make customization difficult
  • Continued prevalence of heavy BeanModel-based models and stores and expensive run-time massaging of data; someone should really teach them about generators
  • No visible effort to take advantage of, or at last synchronize with, up and coming GWT best practices like MVP, dependency injection, command pattern, and compile-time optimization rather than run-time inflation
  • Many things… are still… so slow; forcing your user to choose between waiting while a component spins in IE 7 vs. having it load lightning fast but not work correctly in Safari or Chrome is so web 1.0

I’ve heard that GXT 2.0.1 is just around the corner with “many fixes”. Right.

,

2 Comments

Spring4gwt, or Spring’s harmony for GWT

I’ve had an idea itching at me for awhile now, which started shortly after building a complex enterprise application using GWT connected to Spring services on the server. There are countless blogs out there describing various ways to wire up Spring with GWT, and Google’s own Gin is quite adequate for client-only dependency injection. But what I’d really like is something that ties this all together, and in the true spirit of GWT, makes it easy for a seasoned Java developer to apply proven, consistent DI practices in both the client and server using the Spring knowledge they likely already have.

My vision is basically this:

@Component
public class SomeGWTComponent {

	// Some other client-side component
	@Autowired
	private MyWidget widget;

	// A remote service proxy to a server-side Spring service
	@Autowired
	private MyService service;

	public void doSomething() {

		widget.doClientStuff();

		...

		service.doServerStuff("data", new AsyncCallback<String>() {

				public void onFailure(Throwable caught) {
					...
				}

				public void onSuccess(String result) {
					...
				}
			});
		}
	}
}

It’s important that MyService is a vanilla Spring service on the server – no extension of RemoteServlet required – and that MyWidget is any other GWT component. Injection should occur when the component is created, potentially with varying scopes just like on the server, and potentially also with @PostConstruct support for code to be executed after injection, leaving the constructor available for any pre-injection initialization. And finally, as much work as possible should be done during GWT compile minimize the run-time cost.

The approaches to GWT lookup/injection I’ve seen out there have at least one the following gaps:

  • They’re client-only (Gin)
  • They’re largely run-time, and slow (MVC helpers in component libraries like GXT)
  • They involve SpringMVC or other unnecessary server-side complexity (most blog guides)

So I’m going to try to bring this altogether in one simple library with the following goals:

  • Simplicity: Access Spring services from the client through a generic exporter; no service-specific mappings in web.xml, forced type hierarchy (services should be existing Spring POJO’s), or dependency on SpringMVC. In other words, when a new Spring service is added to the server it should require zero configuration changes to be accessible in the client if desired.
  • Consistency: Client-side dependency injection with native Spring look and feel; freedom to inject private members, via constructor, or via getters/setters with same Spring annotations and conventions that are already familiar.
  • Performance: Do all the heavy lifting with GWT generators to keep the client lean.

Behold, spring4gwt where I’ll do my best to make this a reality! The initial version captures objective #1, bringing together a generic servlet for exposing Spring services without turning each into its own RemoteServlet mapped in web.xml. Up next: accessing those services with Spring DI in the client!

, , , ,

13 Comments

GXT 2.0-M2 upgrade experience

Recently I shared my GWT 1.6 and GXT 2.0-M1 upgrade experience which was quite underwhelming on the GXT front. In the past week my team went ahead an upgraded to GXT 2.0-M2 to take advantage of some specific changes we’d noticed in svn.

For the most part 2.0-M2 didn’t introduce new breaking changes beyond M1. In our project, the only obvious differences were new parameters to some renderers that were easily converted. Functionally, most things seem to work like M1 as well – just a few minor tweaks here and there. However, on the performance front there seem to be some incremental improvements: one example is TreeTable, where we’ve had problems with render time growing linearly with the number of children (over 100ms/item in IE7 – that’s over a minute for a 100 item tree!). It’s still based on the legacy Table paradigm rather than their newer Grid (see some GXT notes on the difference here), but has improved to the point where we can use it for a moderately sized TreeTable and re-build/render a new TreeTable in under 10 seconds. The existence of Table vs. Grid is a good example of 2.0-M2 still exposing several different architectural approaches to components, but at least the ones being actively pursued seem to be headed in the right direction.

Other than that M2 has been a worthy upgrade from M1. I’d fully expect anyone upgrading from 1.2.x to 2.0-M2 to still experience a lot of pain, but if you’re already on M1 then it makes sense to go ahead and get all these fixes. Our M1 build was actually an svn checkout that already had a couple weeks’ worth included, and M2 is certainly a much higher quality preview than either that or the original M1 release. Moving from M1 to M2 will give you a bunch of fixes and keep you in sync with the API for a very minimal amount of effort.

,

No Comments

GXT 2.0-M1 dynamic sizing issue

Recently I commented on a rather severe change in GXT 2.0-M1 with regard to dynamic sizing via percentages not being converted to final HTML as expected with some components. For anyone else experiencing this issue, here’s my support thread which also includes a very simple example app illustrating the problem.

So far our workarounds have been:

  1. Explicit fixed sizes, ugly but easiest in some tricky spots (not resize-proof)
  2. Fixed sizes derived from parent, e.g. parent passes in its height/width minus any margins and borders (resize-proof only if parent size changes are manually propagated down)
  3. Add additional wrappers/children so that the problematic components delegate to, or inherit from, one that works (resize-proof only if parent size changes are manually propagated down)
  4. Implement “smart” post-render sizing based on actual height/width of parent (resize-proof as long as sizing methods are called on resize, most robust, probably the most invasive)

,

1 Comment

GWT 1.6 and GXT 2.0-M1 upgrade experience

This past weekend I had a chance to upgrade a GWT/GXT project earlier than expected. We’ve had considerable pain on the current version of GXT and hoped this might lessen it; sadly, the grass was not much greener on the other side.

GWT for its part was a fairly straightforward process, even with all the significant “breaking” API changes like a new war-based project layout, new eventing model, new compiler, and revamped hosted mode (see the complete list here). The steps involved were essentially:

  • Bring in the new jars
  • Move resource directories and web.xml into the new preferred war location
  • Fix compile errors (mostly new event/listener type and getters/setters replacing public members)
  • Change the compiler and hosted mode classes to the new ones, with the new args
  • Toy with the hosted mode and build classpaths so that Selenium is in the classpath first for unit tests, but GWT is first for hosted mode (because our project uses Selenium for UI tests and both Selenium and GWT are nice enough to bundle Jetty – and different versions, no less – as dependencies; Selenium, please move to Jetty 6 already!)

Additionally, each developer on the project had to disable/re-enable their GWT profile in Eclipse to have it detect 1.6 mode and re-create any run targets (not a big deal really, since the GWT Eclipse plugin makes this much easier than before!).

We have run into one intermittent problem worth noting: When attempting to run our client with a mock services stack (simple web.xml with local servlets that return test data), hosted mode will occaisonally freeze on startup. Debugging has revealed that our RPC calls are initiated but never returned. Base on the randomness and timing of the freeze it almost looks like a race condition where the mock services aren’t deployed as fast as the client, and hosted mode gets stuck in a loop waiting for the return on a call that was never received. Since our application has a rather custom setup where we run RPC against a different context in production (separate services war inside the same container), and this is also something we’ve attempted to mock, it’s not bad as a single issue; our workaround is to simply run the mock service stack externally on Jetty via an ant task and use hosted mode solely for deploying the client.

GXT on the other hand was a nightmare. GXT issues were the main driver behind our early upgrade – since the 2.0 release date keeps moving we decided to bite the bullet now and try M1 in hopes that it would fix more than it breaks. The obvious breaking changes were minimal – just some type changes, event differences, and slight re-arrangement of classes. But in terms of functionality the visual layout of the application was immediately wrecked on upgrade due to a number of blatant bugs (or very questionable behavior changes). Note that after our initial run-through we downloaded the very latest 2.0 snapshot from svn (as of 4/26/2009) and built that with similar results:

Percentage/pixel sizing problems
On components using a CardLayout (like TabPanel), height and width percentages get changed into raw pixels. In other words, calling setHeight(“100%”) results in HTML with height=100px embedded in it. This is incredibly annoying and I can’t overstate how thoroughly it breaks an application. Since our application sizes very dynamically and we intentionally avoid fixed size like the plague, it immediately became a mangled cluster of 100×100 boxes. Entertaining yes, but difficult to fix. We’ve ended up implementing a mixture of fixed heights/widths on the affected components and trying to delegate more explicitly to parent sizes until there’s a permanent fix.

Tighter coupling
Components seem less designed for extension, or at least more tightly coupled to each other and the DOM; for instance, several components that we’d extended and overridden onRender() for specific functionality blew up spectacularly, requiring that we override and assuage other methods to make them content again. The changes aren’t bad, but a framework doesn’t feel well thought-out when I’m forced to hack things one way in release x, then hack them a different way in release y.

CSS changes
To the GXT team’s credit the CSS tags used by objects are largely unchanged, however the css behavior and default values of many components are different; this was mostly an impact where we’d intentionally hacked things in CSS to make them look correct cross-browser and the hack was no longer necessary (or worse, now causing an issue). Our bad for hacking, but again, it sucks when a framework forces you into this, then keeps changing it.

New features incomplete
Any of the big “new” features we tried like HBoxLayout and VBoxLayout seem incredibly incomplete or broken. For example, attempting to use a VBoxLayout resulted in a panel rendering partially in the correct spot with its children lined up at the bottom of the screen, below the rest of the application; source inspection revealed some serious div madness going on. Based on this state of fail we’re not planning to dive further into any new features until it’s GA.

All in all the net change in GXT 2.0 as of M1 seems to be slightly better performance and a mild set of new features, yet with most of those new features broken and some very serious and annoying core bugs such as the percentage/pixel issue. I really hope they’re hard at working fixing these, as the pushed release date may suggest, and that the final release has some honest documentation on ALL breaking API changes and known issues, especially since documentation is something GXT has always lacked. I would highly recommend against anyone taking 2.0-M1 unless pain is something you enjoy, considering the serious issues and the fact that none of the new features feel usable yet.

GWT 1.6 by contrast is a no-brainer; if you’re lucky enough to be building an app with core GWT and homegrown components and/or another library this will probably make your life much easier. The war layout makes for even tighter integration with Java and is great for projects that are a mix of GWT and static content or other UI technologies. And the new configurability of the compiler makes parallel compilation or even disabling some browser permutations as easy as a few compiler args or lines in your .gwt.xml.

To the Ext guys: I really hope you have something better in store for us by 2.0 GA! The team I work on has many developers who’re new to GWT development and have backgrounds in custom AJAX, Flash, or C# UI’s. GXT 2.0 is continuing to build their impression that this technology is a hack that brings the “worst of both worlds”: they see a complex framework that’s lacking many features, yet is difficult or impossible to extend in a way that will be a) consistent cross-browser and b) not break completely on upgrade. Combined with the lengthy build/deploy time to test small changes in real browsers, it’s feeling like a net loss vs. straight AJAX (in JavaScript) or, better yet, another RIA technology completely such as Flash or Silverlight.

It’s worth noting that none of the pain points I’m belaboring, especially when it comes to CSS weirdness and cross-browser testing, are anything unexpected for traditional web application development. But they should not be the norm for GWT: a library on top of GWT that experiences all these pitfalls with regularity seems to miss the point. We expect something in return for long compile times and difficult-to-debug generated code; certainly more than just the convenience and familiarity of Java versus JavaScript.

But as someone heavily vested in a GXT project, here’s hoping even more that it shapes up a bit by 2.0 GA!

, ,

16 Comments