Skip to content

GWT Mini Pattern: Configuration Reader

I’ve written about configuration options to GWT widgets before. Basically, the idea is that you have some configuration that lets the widget change behavior without redeploying or compiling code. In fact, nontechnical users (like designers) can change configuration, if it’s documented. These are the ways I know to specify configuration:

Meta tags

In the page:

<meta content="bar" name="foo" id="foo" />

Updated 4/1/2008, to have id in the meta tag attbute.

In your code:

String var = DOM.getElementProperty(DOM.getElementById("foo"), "content");

You can also request only Boolean and Int:

String var = DOM.getElementPropertyInt(DOM.getElementById("foo"), "content");

This is simple, all browsers ignore these tags, and you can place them anywhere in a page and get them read. However, attributes can only contain strings.

Hidden spans

In the page:

<span id="foo" style="display: none">bar</span>

In your code:

String var = DOM.getInnerHTML(DOM.getElementById("foo"));

This is a good choice if you want configuration to be more structured than what a tag attribute can provide--you can parse the 'var' string further.

Javascript using jsni

<script type="text/javascript">
var ID = 'bar';
</script>

And in your code:

private native String getIDAsString()/*-{
if ($wnd.ID == undefined) {
return "";
} else {
return $wnd.ID;
}
}-*/;

private Integer getID() {
Integer id = new Integer(-1);
try {
id = Integer.valueOf(getIDAsString());
} catch (NumberFormatException ignore) {}
return id;
}

Integer foo = getID();

This method is great when you have variables that are used by other javascript components that you'd like to leverage for your GWT component, or if you have a really complex configuration that is multiple levels in structure.

Javascript using dictionary

(As outlined here and here.)
In the page:

<script type="text/javascript">
var dictionary = {
foo: "bar"
};
</script>

In your code:

Dictionary theme = Dictionary.getDictionary("dictionary");
String bar = theme.get("foo");

This is good for simple hash datastructures. I haven't tried it, but from the documentation, it doesn't look like it supports anything past String key value pairs, and your module must inherit from com.google.gwt.i18n.I18N.

Regardless of your configuration method, I've found myself using a ConfigReader to isolate this logic. It looks something like this:

public class ConfigReader{

private final boolean opt1;
private final String opt2;

public ConfigReader(){
// init opt1 and opt2 using one of the four methods above.
}

public boolean isOpt1() {
return opt1;
}

public String getOpt2() {
return opt2;
}
}

Thunderbird Plugins: Lightning

If you live in your email and you use Thunderbird, I’d recommend taking a look at Lightning.  It’s a calendaring plugin to Thunderbird.  It has changed the way I schedule my life–I used to have a mishmash of emails, paper calenders, todo lists  on the back of envelopes and memories that coordinated my life.  Now I just have one place that I go to.  You can have calendars on remote servers, using HTTP (readonly), webDAV or ftp, multiple calendars, and reminders.  It’s still beta software (version 0.7) and under active development, so, of course, buyer beware, but I’ve found it to be quite useful.  If you want to follow future progress, visit the Mozilla Calendar Weblog.

GWT Mini Pattern: Use a span to enable

Since I last checked, you aren’t able to have more than one GWT module on a page.  However, each widget is independent, so it makes a lot of sense to package them up as separate modules.  Then, you have one module that inherits from all of the other ones, and therefore all the widget code gets executed.  Except, sometimes it makes sense for a widget to be on one page and not another.  The easies way I have found to do this is to use a span tag with a unique id to mark a page for a component.  Sometimes the span tag is where the component places itself–other times it just serves as a
marker for a component which manipulates the DOM in other ways.

The code often looks like this:

RootPanel rp = RootPanel.get(SPAN_ID);
if (rp != null) {

MyComponent obj = new MyComponent();
rp.add(obj);
}

Now, if we’re on a page that this component does not make sense on, it never gets intialized, no network calls are made, etc.

One issue is that if you want to have the component in more than one place on the page, you need to handle that with special cases.  You can simply use the same id twice, because it is bad form to have more than one element with the same id on a single page–ids are supposed to be globally unique on a page.  If you could use a special tag, that’d be nice, but GWT does not support getElementsByTagName.

GWT Mini Patterns Introduction

GWT can be used to create applications and widgets. I’ve done both, but the feeling I get from reading the newsgroups is that a lot of people are using using GWT to build network applications rather than smaller chunks of functionality. So, I’m going to write a number of posts about GWT component patterns.

First off, what’s a GWT component? In my mind, it is a small bit of functionality that is better run on the client than on the server. It can have server interaction. It does not occupy the entire screen, and has to integrate into an existing HTML based application. Components are relatively self contained and can be dropped in multiple places across a website, or across different websites.

The patterns in this category are not that complicated. They just seemed to be popping up in my code more than once and I thought it’d be nice to document them. Check back here for more as I write them.

[tags]patterns,google web toolkit[/tags]

Using ‘tasks’ in Eclipse

Update, 11/13/2009:  If you are looking for help with tasks using Mylyn (integrated into later versions of eclipse), you don’t want this post.  Instead, you’ll want to read and watch the resources here.  This post is all about simple text based code markers, not Mylyn’s implementation.

In Eclipse (version 3.2–one revision behind the current latest), I use a feature called ‘Tasks’. Using this feature, I can, anywhere in a file managed by Eclipse, put in a tag like ‘XXX’ and write a note to myself. It’s very handy because when I’m developing, I’ll often think of a problem or situation that I’d like my code to handle, but not have time to deal with it just then. I could add it to a bug tracker, or an excel spreadsheet, or write it down, but I find adding it to the source code works just as well. Then, I can use the ‘Tasks’ view in Eclipse to gather all of these notes at a later time, and deal with them one by one. I add it using this type of comment (for java–if I add the task in an XML file, I use XML comments):

//XXX need to revisit this class.

The way you include the tasks view in the java perspective is: go to the java perspective, then choose ‘Window’ from the menubar, then ‘Show View’ then ‘Tasks’. According to the help, Tasks are usually only shown in the ‘Resources’ perspective.

My one gripe with tasks is that it seems to be easy to create them, but darn hard to delete them. You can add new task tags via this path: ‘Window’ / ‘Preferences’ / ‘Web and XML’ / ‘Task Tags’, and use the ‘clean and redetect task tags’ button. This does appear to pick up new tasks (or tasks marked with tags that you’ve added), but doesn’t seem to remove tasks that are no longer marked in the source code (whether they are no longer marked because you removed them from the source code, or because you removed that task [TODO] tag from the list of task tag).

If you add a task via the mouse, you can remove it by right clicking on the checkbox. However, that doesn’t remove the task comment from the source file. Also, if you add a task via a comment, you cannot mark it done in the ‘Task’ view.

What I’d like is some synchronicity between the source file and the view. If I add a task in the source file, it should show up in the ‘Task’ view. If I then delete that line from the source file, I’d like the view to reflect that. If I mark it as completed in the view, then choose ‘Delete Completed tasks’ from the context menu, the line in the source file should be removed as well.

Am I missing something here? Am I using tasks incorrectly?

I looked through the Eclipse help, on google, and in the Eclipse newsgroups but did not find anything that helped. No mention of this issue in the release notes for version 3.3. Browsing around the buglist didn’t turn up anything that applied to what I want to do (via a quick scan).

I’ll probably file a bug sometime soon, but should really review all the entered bugs to see if someone else has my issue. In the meantime, I’ll just bleat a bit here.

[tags]eclipse,tasks view[/tags]

The ant jar task and duplicate files can cause bizarre behavior and missing/incorrect files when unzipping

I just ran into some bizarre behavior. I’m building a web application on Windows XPSP2, using Ant 1.6.1. The application worked fine. Then, I added one more copy instruction, to move a GWT component I’d just added to the appropriate place in the war file. Suddenly, the application ceased to work.

After a few hours of tracking down the issue, I found that it didn’t matter whether it was the new GWT component or an old one; it didn’t matter whether the copy went to the same directory or a new one–simply adding the new set of files caused the issue. Then I noticed that the unzipped version of the application differed. In particular, the configuration files differed. That explained why the application wasn’t working–it wasn’t configured correctly.

But, why were the configuration files different?

I examined the generated jar file. When I unjarred it, the configuration files were correct. I was using the jar command, whereas the ant script was using unzip. I made sure the jar file was copied correctly. I made sure the old directory was deleted, and that the ant unzip task would overwrite existing files. Still, no fix–I was seeing the incorrect configuration files.

Then, this part of the jar task documentation jumped out at me:

Please note that the zip format allows multiple files of the same fully-qualified name to exist within a single archive. This has been documented as causing various problems for unsuspecting users. If you wish to avoid this behavior you must set the duplicate attribute to a value other than its default, “add”.

The other possible values for the duplicate attribute to the jar task listed are “fail” and “preserve”. It doesn’t explain what the other options actually do; “fail” causes the jar task to fail when duplicate files are encountered. This seems to be sane default behavior, and I’m not sure why it’s not the case. “preserve” seems to preserve the first file added, and doesn’t add duplicates, but doesn’t tell you that duplicates exist.

Update, 2:09:   “preserve” does tell you that duplicates exist, in this form: WEB-INF/web.xml already added, skipping

I had, for a variety of reasons, a jar task that was adding two sets of the configuration files, with the same names and paths, to the war file. Something about adding a few extra files seemed to flip a switch, and change existing behavior. Whereas before, the unzip task picked the correct configuration file, now the unzip task picked the incorrect file. I don’t know more than that, because I didn’t dig down into the source.

The answer is to move the correct files to the top of the jar task, and change the “duplicate” attribute to be “preserve”.

I hope this post saves someone a few hours of banging their head.

[tags]ant, jar files, duplicate files, headbanging[/tags]

InvocationException using GWT RPC and custom objects

If you are using GWT 1.4 and sending custom objects over the wire, and see an exception like this in your log files:


2007-11-09 11:06:13 Exception while dispatching incoming RPC call
com.google.gwt.user.client.rpc.SerializationException: Type 'com.foo.common.data.User' was not assignable to 'com.google.gwt.user.client.rpc.IsSerializable'
and did not have a custom field serializer.  For security purposes, this type will not be serialized.
at com.google.gwt.user.server.rpc.impl.LegacySerializationPolicy.validateSerialize(LegacySerializationPolicy.java:136)
at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter.serialize(ServerSerializationStreamWriter.java:331)
at com.google.gwt.user.client.rpc.impl.AbstractSerializationStreamWriter.writeObject(AbstractSerializationStreamWriter.java:81)
at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter.serializeValue(ServerSerializationStreamWriter.java:259)
at com.google.gwt.user.server.rpc.RPC.encodeResponse(RPC.java:574)
at com.google.gwt.user.server.rpc.RPC.encodeResponseForSuccess(RPC.java:442)
at com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:530)
at com.google.gwt.user.server.rpc.RemoteServiceServlet.processCall(RemoteServiceServlet.java:265)
at com.google.gwt.user.server.rpc.RemoteServiceServlet.doPost(RemoteServiceServlet.java:187)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:760)

You may be very interested in this release note from the 1.4.59 release:

RPC now generates a serialization policy file during compilation. The serialization policy file contains a whitelist of allowed types which may be serialized. Its name is a strong hash name followed by .gwt.rpc. This file must be deployed to your web server as a public resource, accessible from a RemoteServiceServlet via ServletContext.getResource(). If it is not deployed properly, RPC will run in 1.3.3 compatibility mode and refuse to serialize types implementing Serializable. Updated 3/6/2011 to correct link location.

This exception caused me a world of grief, first because I wasn’t seeing anything in standard out (it logged to a different file), then because I couldn’t find the source of LegacySerializationPolicy, then because I have the gwt source in one directory, but because of rewrites, it appears to be served from another directory. It manifests on the client side as an InvocationException with a fantasticly unhelpful error message.

The fix is simple: copy the serialization policy file to wherever the GWT files appear to be served from.

FogBugz world tour, Boulder edition

I went and saw Joel Spolsky’s talk about FogBugz6 tonight. It seems to be quite the powerful software development tool. But I’m afraid that it seems to suffer like every tool–it forces you into certain methods of development. For example, there’s no way to ensure that every bug entered is viewed by QA. Now, that isn’t a problem for the teams I currently work on, but I can see it being a problem for teams I have worked on. Joel mentioned very valid reasons for doing this, but they only seem valid for the subset of development teams that FogBugz targets.

In fact, as I left, almost every conversation I heard was about the product, and how people could fit it into their process, rather than use the process it gives you. Because FogBugz really is more than a bug tracking system–it now goes from documentation/requirements gathering all the way to estimation to bug tracking to customer support. FogBugz appears to be a tool that is used in almost the entire software development life cycle–hey look, it’s RUP lite.

But I’ve used never version 6, and I’m sure there are significant wins. My other concerns are that the software estimation parts sound like they’re 1.0 features (just from the words he used–at best 1.1 since they used FogBugz6 to develop FogBugz6); I’d rather wait until the features are more settled. I’m sure you could use just the bug tracking system, and they’ve certainly taken the ‘Web 2.0’/instant response/make it feel like a desktop application ideas to heart. The cost is another concern; while minimal, it is greater than $0. On many projects I’m on, just using any bug tracker, let alone an entire software development tool, is difficult, and you can’t beat stealth bug tracker installs. (I’m on record as saying “I have to say that I think the open source solutions (Bugzilla and PHPBT) are going to eat the commercial solutions’ lunch for small projects, because they are a cheaper substitute with all the required attributes”, just as an FYI.)

One thing that really surprised me at the talk is how many folks were there evaluating FogBugz as opposed to seeing Joel speak. Around one third of the audienced had used or was using FogBugz. Joel opened up the floor to questions, and every single one except one (of mine) was about features or flaws in FogBugz. I mean, this is the guy who wrote the Joel Test and no one took the opportunity to ask him general development questions, even though he said he’d field them. I don’t know what the deal was.

Will I give FogBugz a try? Not right now. But I’ll keep an eye on what they’re doing.
[tags]software development tools, bug tracking, fogbugz, joelonsoftware[/tags]