TurboManage

David Chandler's Journal of Java Web and Mobile Development

  • David M. Chandler


    Web app developer since 1994 now working for Google and residing in Atlanta with the wife of my youth and our five children. My current side project is a not-for-profit startup using GWT on AppEngine. In my "spare" time, I take pictures, preferably of Rocky Mountain National Park.

  • Subscribe

  • Enter your email address to subscribe to this blog and receive notifications of new posts by email.

    Join 134 other followers

  • Sleepless Nights…

    May 2012
    S M T W T F S
    « Apr    
     12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
  • Blog Stats

    • 344,154 hits

Archive for the ‘Headsmack’ Category

GWT 2 upgrade almost painless

Posted by David Chandler on January 13, 2010

I took the plunge and upgraded my Google Eclipse plugin and SDKs to GWT 2 using the normal Eclipse update mechanism. The new development mode threw me for a bit of a loop, but that’s the only problem so far. The GWT 2 docs say that the browser will automatically prompt you to download the Google Web Toolkit Developer plugin, but that wasn’t happening for my existing GWT project, only new ones.

The solution was simply to delete the generated app directories under the war folder, and clean and rebuild the project. Then I was prompted to download the plugin as expected, and the browser makes the connection to Eclipse so I can view the GWT logs.

So far so good. I’m anxious to try out the new UIBinder templating and hopefully simplify page layout issues…

Posted in Google Web Toolkit, Headsmack | Leave a Comment »

GWT layout gotcha

Posted by David Chandler on January 12, 2010

I previously wrote about GWT layout with HTML and CSS. One gotcha I’ve found is that you must be careful not to attach a widget to a DIV nested inside a DIV that is attached to a widget. By way of negative example, consider this HTML:

<div id="main">
	<div id="app">
		<div id="detail_header"></div>
	</div>
</div>

Because the detail_header DIV is nested inside the main DIV, this will fail:

		RootPanel.get("main").add(contentContainerPresenter.getDisplay().asWidget());
		RootPanel.get("detail_header").add(userPresenter.getDisplay().asWidget());

The error message is not particularly obvious, which is why I wrote this post:

[ERROR] Uncaught exception escaped
java.lang.AssertionError: A widget that has an existing parent widget may not be added to the detach list
at com.google.gwt.user.client.ui.RootPanel.detachOnWindowClose(RootPanel.java:122)

The solution is simply to untangle the DIVs by making them siblings instead of nested:

<div id="main">
	<div id="detail_header"></div>
	<div id="app"></div>
</div>

Posted in Google Web Toolkit, Headsmack | 2 Comments »

GWT-RPC serialization gotchas

Posted by David Chandler on November 23, 2009

In gwt-dispatch, Action and Result classes extend java.io.Serializable; however, I have  bumped up against this error a few times:

Type 'com.your_company...' was not included in the set of types which can be serialized by this SerializationPolicy or its Class object could not be loaded.

I get this error for one of two reasons, and wanted it on my blog so I can search it next time :-)

1. I forgot to include a no-arg constructor.

2. The type of one or more class fields in the Action or Result class is not Serializable (usually a domain object for which I’ve forgotten to implement Serializable).

As a last resort, delete the *.gwt.rpc files in your war/app directory, clean and rebuild. But the problem is usually one of the above…

Posted in Google Web Toolkit, Headsmack | 4 Comments »

Weird serialization error in AppEngine

Posted by David Chandler on November 21, 2009

My previous post discussed a very cool way to do background processing in AppEngine using Deferred.defer. Unfortunately, the AdminEmailTask example I posted results in a cryptic error when the task is dequeued and the Deferred servlet attemps to deserialize it:

com.newatlanta.appengine.taskqueue.Deferred deserialize: invalid type code: 00

After nearly a day’s worth of experimentation, I am really weirded out by what I’ve found: the problem seems to be the name of the private field “msgSubject” in AdminEmailTask. I tried shorter names, longer names, and other names without any problem. I changed the class name, moved it into a different package, and generally pulled my hair out until I simply tried changing the name of the field. At first, I thought it was this JDK bug, but I wasn’t using an array type. Nevertheless, I subclassed ObjectInputStream and overrode the resolveClass method as per the bug’s workaround, only to find out that AppEngine’s implementation of ObjectInputStream doesn’t call the overridden resolveClass and throws a security exception on enableResolveObject(true).

I can only guess that the field name “msgSubject” results in a binary sequence that is somehow special to AppEngine’s implementation of ObjectInputStream, or perhaps it’s a bug in the JDK.

At any rate, if you get the java.io.StreamCorruptedException with invalid type code: 00, try renaming your class fields! I really, really hope I’m mistaken about this.

Posted in AppEngine, Headsmack | 1 Comment »

Tips on organizing GWT modules

Posted by David Chandler on November 19, 2009

My current project is at the point where I’m starting to work on an administrative UI. I wanted to package it as a separate GWT module in order to not clutter up the main application module. There is some code such as the domain model that is shared between the main app and the admin code, so the question is how to organize the modules in order to share code between them.

My first attempt was to have the admin module simply inherit the main app module named ROA in admin.gwt.xml, like this:

	<inherits name="com.roa.app.ROA" />

This had two undesired results:

  • Both modules declare an entry-point, so GWT tries to load both, beginning with the inherited module.
  • At GWT compile time, all the code from the inherited module was duplicated under the admin module in the war structure.

My next attempt was to have the admin and app Java packages each point to a third sister package called “common” containing the domain model and other common code. Java is happy with this, but in order for GWT to compile the common code into JavaScript, you must make it a module. So now there are three packages, each with its own module:

admin.gwt.xml
app.gwt.xml
common.gwt.xml

Admin and app each have entry points and inherit the common module, which does not define an entry point. This works fine.

In the common module, I use the source tag to include multiple directories instead of just the default client directory. Note that if you specify one or more source directories, GWT no longer compiles the client directory by default, so you have to explicitly include it, as well:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 1.7.1//EN" "http://google-web-toolkit.googlecode.com/svn/tags/1.7.1/distro-source/core/src/gwt-module.dtd">
<module>
	<inherits name="com.google.gwt.user.User" />

	<source path="client" />
	<source path="domain" />
	<source path="presenter" />
</module>

Also, I moved the “public” directory containing CSS and images from the admin and app packages into the common module, and discovered that GWT does not create a “common” directory in the war, but rather copies the contents of the public folder from the inherited common module into both the admin and app module directories. That’s OK, though, as my CSS and images now exist in only one place in source control.

A final note: thank goodness for Eclipse refactoring tools. The easiest way to move a package (say, com.roa.app.domain to com.roa.common.domain) is to select it in the Project Explorer, then right-click, Refactor, and Rename… It’s a bit non-intuitive to use Rename rather than the Move command, but the latter appears to work only for moving packages to another project or source folder, whereas rename allows you to “move” it within the current source folder. Eclipse automatically fixes all the package and import declarations in affected code (whew!).

Posted in Eclipse, Google Web Toolkit, Headsmack | 8 Comments »

Don’t ever do this in GWT

Posted by David Chandler on October 16, 2009

		<div id="something" />

This cost me a night and a day in the deep. It seems to freak out the GWT DOM class such that subsequent calls to it for other IDs fail, in my case causing the screen to vanish entirely. This works fine:
		<div id="something"></div>

Posted in Google Web Toolkit, Headsmack | 4 Comments »

gwt-presenter Hyperlink gotcha: URL in address bar getting wiped out

Posted by David Chandler on October 8, 2009

Just a quick note in the Headsmack department related to navigation between views with gwt-presenter: if you attach a ClickHandler that fires a PlaceRequestEvent to a Hyperlink, but forget to supply the history token, the browser will correctly navigate to the requested Place; however, the placeId and any parameters on the URL will immediately be wiped out in the browser address bar. The reason is that after the ClickHandler fires, GWT replaces the URL in the address bar with the history token from the Hyperlink, which, in the example below, is empty because it’s never set.

		// Don't do this
		Hyperlink hyperlink = new Hyperlink();
		hyperlink.setText("click here");
		hyperlink.addClickHandler(new ClickHandler()
		{
			@Override
			public void onClick(ClickEvent event)
			{
                eventBus.fireEvent(new PlaceRequestEvent(placeRequest));
			}
		});

This is a case of making it too hard (or more likely, accidentally leaving the ClickHandler in place when you decide to try a Hyperlink instead of a Button). Thanks to the gwt-presenter PlaceManager, which listens for History ValueChangeEvents, all you need is this:

		Hyperlink hyperlink = new Hyperlink("click here", placeRequest.toString());

That’s so clean it makes me want to use Hyperlinks everywhere.

See also a previous post on this topic.

Posted in Google Web Toolkit, Headsmack, Model-View-Presenter | Leave a Comment »

gwt-dispatch and com.google.gwt.user.client.rpc.SerializationException

Posted by David Chandler on October 2, 2009

I’d written a new gwt-dispatch ActionHandler with corresponding Action and Result classes and was getting the above exception. The cause turned out be very simple: Action and Result classes implement java.io.Serializable and GWT-RPC therefore requires that they have an empty constructor. So when you get the yellow squiggly in Eclipse that prompts you to generate a serial ID, add an empty constructor, too, and save yourself some grief.

Posted in Google Web Toolkit, Headsmack, Model-View-Presenter | Leave a Comment »

JSF Welcome File Gotcha

Posted by David Chandler on March 6, 2009

When using web.xml’s welcome file capability to specify your application home page, make sure your editor (hint: Eclipse Web Tools?) doesn’t put in a leading slash.

Right:

<welcome-file-list>
<welcome-file>homePage.jsf</welcome-file>
</welcome-file-list>

Wrong:

<welcome-file-list>
<welcome-file>/homePage.jsf</welcome-file>
</welcome-file-list>

The leading slash in the second example will trip up JSF such that when you submit a form on the home page, it will simply reload the home page on the first click, and then do the action and navigate to a new page only on the second click. If you look closely in the URL, you’ll see a // in the path that causes the problem. Welcome files work in any directory (thus, no slash is needed), but Eclipse WTP appears to add a preceding slash when using the file chooser.

Note: if you’re using Tomcat and specify a welcome file with a jsf extension as shown, you’ll also need to create a dummy file with that extension in addition to the real JSP or .xhtml (facelets) view template to satisfy Tomcat’s welcome file existence check. I create a .jsf file with a single line:

<%// Dummy file to trick Tomcat into supporting welcome-file-list –%>

Posted in Headsmack, JavaServer Faces | Comments Off

 
Follow

Get every new post delivered to your Inbox.

Join 134 other followers