Archive for July, 2009

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

Stacking GWT 1.6 workers with ant parallel for super-fast builds

Having just built a new machine around a Core i7 950 enthusiastically overclocked to 4.2gz, I couldn’t help but explore the possibilities of a lightning-fast GWT compile. I regularly build a project that involves a core services war that’s pure Java along with a GWT 1.6 war consisting of two modules that requires 3 permutations each, all wrapped into an ear at the end.

Historically this took about 3 minutes running serially on a reasonable Core 2 Duo. It would run the core services war build, then the GWT build one module at a time, each using GWT 1.6′s -localWorkers 2 to at least make use of both cores.

The potential of 8 concurrent threads across the i7′s four cores and the presence of two GWT modules plus another build compelled me to resurect some old-school Ant parallelization to stack as much work as possible during the build. With a bit of tweaking it’s easy to have ant running multiple targets – some GWT and some non-GWT – at the same time, so that entire modules, not just permutations, are built in parallel. For example, something like


<target name="gwt">
	<java classname="com.google.gwt.dev.Compiler" fork="true" failonerror="false">
		<arg value="module1" />
		<arg value="-localWorkers" />
		<arg value="1" />
	</java>
	<java classname="com.google.gwt.dev.Compiler" fork="true" failonerror="false">
		<arg value="module2" />
		<arg value="-localWorkers" />
		<arg value="1" />
	</java>
</target>

becomes


<target name="gwt">
	<parallel threadsperprocessor="1">
		<java classname="com.google.gwt.dev.Compiler" fork="true" failonerror="false">
			<arg value="module1" />
			<arg value="-localWorkers" />
			<arg value="4" />
		</java>
		<java classname="com.google.gwt.dev.Compiler" fork="true" failonerror="false">
			<arg value="module2" />
			<arg value="-localWorkers" />
			<arg value="4" />
		</java>
	</parallel>
</target>

The result was phenomenal. My 3 minute build now takes only 40 seconds! If you have lots of cores available be sure to consider stacking ant parallel with GWT workers for a big improvement. Keep in mind that running many modules in parallel may also require ridiculous amounts of memory (around 600mb per module in my case), but on an i7 system you should have at least 6gb anyway 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!

, , , ,

6 Comments

TDD antipatterns

These TDD antipatterns are hilarious, and all too familar to anyone who’s done test driven development with a wide range of aptitudes on the team!

, , ,

No Comments