Can't instantiate a widget outside of hosted mode

4 views
Skip to first unread message

Jez

unread,
Jun 1, 2006, 2:59:30 PM6/1/06
to Google Web Toolkit
Hi there.

One of the classes I use for serialization classes looks a bit like the
following:

public class Node implements IsSerializable {
/**
* @gwt.typeArgs <Node>
*/
public List nodes;
public String name;

public TreeItem createTree() {
TreeItem item = new TreeItem(name);
for (Iterator iterator=nodes.iterator(); iterator.hasNext();) {
Node childNode=(Node) iterator.next();
item.addItem(childNode.createTree());
}
return item;
}
}

However, I can't write a test for createTree() because I can't create a
TreeItem - it dies with "java.lang.RuntimeException: GWT has not been
properly initialized; if you are running a unit test, check that your
test case extends GWTTestCase".

One quick glance at the source code shows that TreeItem's constructor
uses a static method from DOM, which in its static initializer calls
GWT.create(Class classLiteral) which throws the aforementioned
RuntimeException.

I shouldn't need to fire up the whole GWT hosted apparatus (by
extending GWTTestCase for example) just to instantiate a widget for
testing purposes.

I can see two ways around this - defer initializing the DOM stuff
within TreeItem until it is needed, so I can at least create it and
call non-HTML-generating methods on it, or / and make TreeItem
implement an interface so that I can use this in my Node class. But
these options obviously involve tinkering with the source.

Does anyone have any better ideas?

Scott Blum

unread,
Jun 2, 2006, 12:55:40 PM6/2/06
to Google Web Toolkit
Hi Jez,

My suggestion would be to try to decouple your Node class from TreeItem
if you can. The bottom line is that TreeItem is specifically designed
to run either in hosted mode, or compiled to web mode, but in a browser
either way. What would it mean to instantiate a TreeItem on the
server? Nothing good that I can think of. My advice is to be very
careful with the classes you serialize, this is the gap between the
client and server, so the serializable classes have to work well in
either environment; they have to lie at the intersection of what you
can do on the client and what you can do on the server.

Scott

Jez

unread,
Jun 27, 2006, 7:35:38 AM6/27/06
to Google Web Toolkit
Hi Scott.

Thanks for replying.

The idea is not that the TreeItem would be instantiated in the server
(as you correctly remark this would be pointless) - it would be
instantiated in the client.

So in the above example, you'd create the Node DTO on the server. On
the client, you'd call the createTree() method to populate the TreeItem
widgets. This works just fine.

the problem is I can't write a test for this method without extending
GWTTestCase, since the container is required in order to instantiate
the TreeItem widget.

This is annoying because all I want to do is write a unit test to check
that the TreeItems have been correctly populated - I am not trying to
do functional testing.

My suggestion would be not to require the container upon instantiating
widgets - only when you try to render them. That would fix my problem.
Alternatively, having them implement more specific interfaces would
allow me to use the interface in my DTO instead.

Thanks,

Jez.

Scott Blum

unread,
Jun 27, 2006, 10:18:07 AM6/27/06
to Google Web Toolkit
Hi Jez,

I see the point you're making, but to do deferred element creation
(instead of doing it in the constructor) would have some unfortunate
consequences. Widgets would have become more stateful (has the element
been created or not?). More state means more code (both to execute and
to download) and more possibility of bugs. I don't think it would be a
good trade-off to make these sacrifices just for the sake of creating
Widgets outside of the context in which they naturally live (the
browser), especially when you'd give the developer a false impression
that they can create and use these classes, right up to the point where
they do something that can't work and everything dies. Whenever
possible it's preferrable to fail fast to prevent the developer from
going down an ultimately unfruitful path.

I understand that GWTTestCase is very sluggish right now (and feels
very heavy), but we are working to improve our JUnit performance, and
right now this is the only way to reliably test browser-dependent
client side code.

Hope I made sense with all this,
Scott

bruciadmin

unread,
Jul 2, 2006, 8:05:41 PM7/2/06
to Google Web Toolkit
Hi Scott,

Not that this is a big issue, but I would enjoy seeing more of the
components being able to be instantiated out of hosted mode.

I understand that having the Widgets instantiate and tie in to the DOM
model automatically via static methods aid in convenience. On the other
hand, being able to use components as regular Java make people want to
be able to do all the other things with them which regular Java can do,
like instantiating by themselves. Further, for better testing, we
should be able to instantiate single objects with mock objects as their
dependencies. Summing up, I'd like to see Widgets being as close to
POJO's as possible.

I guess it all comes down to your audience and what they want. I'm sure
many (probably most) of your users so far prefer the convenience of
quickly creating components. However, I believe it will not take long
for the hype to die down a bit, and people will start evaluating Widget
usage patterns in terms of regular O-O development. A pseudo O-O
environment at this point might not satisfy everyone and you may lose a
percent of users to these kinds of issues.

A summary of niggles:
- Excessive usage of static methods == bad coding practice
- Hard wired dependency on static methods in constructor == bad coding
practice
- Minimal usage of interfaces == bad coding practice

I would much rather see objects closer to regular Java beans which have
dependencies on interfaces, rather then concrete objects or static
methods.

Sorry for being so negative - on the whole I've found the Google Web
Toolkit a very good contribution to the community. I'm going to
continue to use it personally for my current project and I'm also
working on a clientside Spring integration project which has been going
quite well.

Cheers,

David L

Reply all
Reply to author
Forward
0 new messages