GWT Recipes
Scenario: GWT is actually remarkably simple to make sense of. The
standard documentation helps, too. But after a short while many simple
questions crop up. This document is intended to answer these questions
(which it sometimes took me a while to figure out).
0. Resources
- Search the GWT google group. This is a treasure trove of good
material. Alas, the information is sometimes a bit scattered (which is
inherent in the nature of the source).
- Roughian Examples:
Very helpful if you need small examples for GWT's classes.
1. Client
1.1. Using existing Java code
- You can only use Java classes whose source code is available. The
source code is needed to generate JavaScript.
- To integrate existing libraries, create a module XML file and
inherit the module whenever you want to use the library.
- You can use <super-source path=""> to provide a source
code that is adapted to the GWT needs
- The source code is nested inside the the package like
my/package/other/package, but the package declaration must still say
other.package.
- The path for both super-source and source can be empty.
Usually, I like nested packages better, though.
- You can take liberties with the source code, especially with
super-source. This comes in handy when methods introduce unwanted
dependencies on other classes: Just make that other class empty and the
dependency is not as much of a problem, any more.
Problems
- A method depends on a class that is too complicated for the
client side or not needed.
- Use super-source (see above). Wish: An annotation for marking
methods whose JavaScript code should not be generated.
- How do I find out if my client-side code is executed as Java
bytecode or as JavaScript code?
1.2. Graphical user interfaces
- Example of manual layout: Mail.java (in samples).
Problems
- DockPanel does not work like BorderLayout when it comes to its
CENTER position!
- You have to set the
cell size to "100%" for it to work like that.
- Debug: setBorder() to 1.
- My widgets don't fill out the complete available area.
1.3. GWT and JavaScript
Problems
- I need to invoke GWT from JavaScript.
2. Server and client-server communication
2.1. Client-server communication
Problems
- Class literals: How can the server tell the client what instances
to create?
- The problem is that GWT.create() only works with class
literals.
This is practically the same as calling a constructor. The reason is
that this method encapsulates a whole (pluggable) suite of functions,
among other
starting RPC on the client side. Solution: Send factories (that must
then be serializable). Wish: An annotation for classes whose class
literals are to be used as factories. Then either GWT.create() or
another client-side method would be used to create instances.
2.2. Serialization
public final class Foo_CustomFieldSerializer {
public static void serialize(SerializationStreamWriter streamWriter,
Foo instance) throws SerializationException {
streamWriter.writeObject(instance.getA());
streamWriter.writeFloat(instance.getB());
}
public static void deserialize(SerializationStreamReader streamReader,
Foo instance) throws SerializationException {
instance.setA(streamRead.readObject());
instance.setB(streamRead.readFloat());
}
}
Wish: Better technique for converting nested server-side data
structures.
Problems
- An interface cannot be serialized: You need at least one
implementing class that is serializable.
- Cannot change an external class to be serializable: Create a
serializable subclass
3. Development and tools
3.1. Simulating a server
environment in hosted mode
- The tomcat/ directory is your friend
- library jars: tomcat/webapps/ROOT/WEB-INF/lib/
- Application-global (non-service) servlets via
tomcat/webapps/ROOT/WEB-INF/web.xml
- Especially if you need to auto-load a servlet.
- Scripts projectCreator, applicationCreator
- Option -ant: generates an ant build file
- Option -out: generates the source code so that it can live
somewhere else (than the current directory)
Problems
- I want hosted mode to start with a different URL.
- Change: *.launch, *-shell
- The paths of my local GWT installation are hard-coded into the
scripts, making it impossible to share them between different
computers. How can I change that?
- Step 1: Define variables (different with each installation,
operating system and/or computer):
- Create two user libraries (Preferences -> Java -> Build
Path -> User Libraries)
- gwt-dev: gwt-dev-{mac,windows,linux}.jar
- Create one runtime variable (Preferences -> Run/Debug
-> String Substitution)
- extra-jvm-argument: "-XstartOnFirstThread" on Mac OS X
(otherwise empty)
- Step 2: Modify the project settings and standard scripts so
that they become installation-independent (and can thus be checked into
version control etc.)
- Use the run dialog to edit the *.launch configuration
- Classpath -> User entries: remove the
gwt-dev-{mac,windows,linux}.jar, add gwt-dev (add
as a library)
- Arguments -> VM arguments: -Xmx256M ${extra-jvm-argument}
- Change the build path to include
gwt-dev-{mac,windows,linux}.jar and gwt-user as a library (not as
a jar).
- Edit *-compile: Remove gwt-dev-{mac,windows,linux}.jar,
gwt-user.jar from its classpath. [Actually, it might be more
complicated than that, this still has to be investigated.]
- Edit *-shell: Same as above
Axel Rauschmayer, created: 2008-04-26,
last change: 2008-05-14