I thought a small tutorial on how to get started with Google Web Toolkit might be in order. The GWT package contains some utilities, but I have found that in order to actually deploy to a Tomcat, you need to do quite a bit of stuff yourself.
This tutorial is based on GWT 1.1.0, Eclipse, Tomcat and Ant. It's assumed that Tomcat is installed somewhere (simply download and unzip/untar, and you're ready to go).
Creating a project
Create a new project in Eclipse - just a regular Java project. Make sure you use separate source and build folders.
Create the following dirs:
lib
lib/build
lib/core
Copy gwt-dev-*.jar and gwt-user.jar from GWT to lib/build.
Download ant-gwt-1.1.0.jar, xdoclet-gwt-module-0.1, gwt-xdoclet-1.2.3.jar, and xjavadoc-1.1.jar and place them in lib/build.
Place gwt-servlet.jar from GWT in lib/core together with any 3rd party libs you're using.
Add all jars (both in lib/build and lib/core) to the Eclipse build path (Right click on a jar and select Build path->Add to build path).
Create the following packages in Eclipse:
dk.contix.gwt
dk.contix.gwt.client
dk.contix.gwt.shared
dk.contix.gwt.service
In the dk.contix.gwt package, create a new dir called "public" and create a new HTML file:
-
<html>
-
<head>
-
<title>Name of module</title>
-
<meta name="gwt:module" content="dk.contix.gwt.Module">
-
<link rel="stylesheet" type="text/css" href="style.css">
-
</head>
-
<body>
-
<script type="text/javascript" src="gwt.js"></script>
-
</body>
-
</html>
The file should be called Module.html in this example.
Setting up build
To actually compile and deploy, you need a ant build.xml file. Use this file:
-
<?xml version="1.0"?>
-
<project default="compile" name="Module" basedir=".">
-
<property file="build.properties"/>
-
-
<path id="classpath">
-
<pathelement location="src"/>
-
<pathelement location="target/classes"/>
-
<fileset dir="lib">
-
<include name="**/*.jar"/>
-
</fileset>
-
</path>
-
-
<path id="sourcepath">
-
<pathelement location="src"/>
-
</path>
-
-
<target name="init">
-
<tstamp/>
-
<mkdir dir="target"/>
-
<mkdir dir="target/classes"/>
-
<mkdir dir="target/web"/>
-
</target>
-
-
<target name="clean">
-
<delete dir="target"/>
-
</target>
-
-
<target name="compile" depends="init,generate">
-
<javac classpathref="classpath" destdir="target/classes" debug="true">
-
<src refid="sourcepath"/>
-
</javac>
-
-
<taskdef resource="dk/contix/ant/gwt/ant-gwt.xml" classpathref="classpath" />
-
<gwtcompile destdir="target/web" optimize="true">
-
<fileset dir="src">
-
<include name="**/*.gwt.xml"/>
-
</fileset>
-
</gwtcompile>
-
-
<copy todir="target/classes">
-
<fileset dir="src">
-
<exclude name="**/*.java"/>
-
</fileset>
-
</copy>
-
</target>
-
-
<target name="generate">
-
<taskdef resource="xdoclet/modules/gwt/doclet.xml" classpathref="classpath"/>
-
<gwtdoclet destdir="src">
-
<fileset dir="src">
-
<include name="**/*.java"/>
-
</fileset>
-
<interface/>
-
<async/>
-
<module/>
-
<servicefactory class="dk.contix.gwt.client.ServiceFactory"/>
-
<webxml output="../target/web.xml"/>
-
</gwtdoclet>
-
</target>
-
-
<target name="deploy" depends="compile">
-
<fail unless="deploy.root" message="You need to define deploy.root in build.properties"/>
-
-
<mkdir dir="${deploy.root}"/>
-
<mkdir dir="${deploy.root}/WEB-INF"/>
-
<mkdir dir="${deploy.root}/WEB-INF/classes"/>
-
<mkdir dir="${deploy.root}/WEB-INF/lib"/>
-
-
<copy todir="${deploy.root}">
-
<fileset dir="target/web"/>
-
</copy>
-
<copy todir="${deploy.root}/WEB-INF/classes">
-
<fileset dir="target/classes"/>
-
</copy>
-
<copy todir="${deploy.root}/WEB-INF/lib">
-
<fileset dir="lib/core">
-
<include name="**/*.jar"/>
-
</fileset>
-
</copy>
-
<copy file="target/web.xml" todir="${deploy.root}/WEB-INF"/>
-
</target>
-
</project>
Creating a launcher
If you want to be able to run the application in hosted mode, you need a launcher. Use this for the purpose - put the following in launch.sh and run chmod +x launch.sh (replace GWT_HOME with the real path to GWT):
-
#!/bin/sh
-
APPDIR=`dirname $0`
-
GWT_HOME=/pack/gwt-linux-1.1.0
-
CLASSPATH="$GWT_HOME/gwt-user.jar:$GWT_HOME/gwt-dev-linux.jar"
-
for i in `find . -name '*.jar'`; do
-
CLASSPATH="$CLASSPATH:$i"
-
done
-
CLASSPATH="$CLASSPATH:bin"
-
export CLASSPATH
-
-
MODULE=$1
-
shitf
-
-
java com.google.gwt.dev.GWTShell -out $APPDIR/www "$@" $MODULE/${MODULE/*./}.html
When you actually have some code, you can run "./launch.sh dk.contix.gwt.Module" to start the application in hosted mode.
Adding some code
Now it's time to add some code. Start with the entry point class, which should be called Module in thie example:
-
package dk.contix.gwt.client.Module;
-
-
import com.google.gwt.core.client.EntryPoint;
-
import com.google.gwt.user.client.ui.*;
-
-
/**
-
* Class description here.
-
*
-
* @gwt.module package="dk.contix.gwt" include="shared,client"
-
*/
-
public class Module implements EntryPoint {
-
public void onModuleLoad() {
-
final HorizontalPanel p = new HorizontalPanel();
-
-
Hyperlink link = new Hyperlink();
-
link.setText("Press me");
-
link.addClickListener(new ClickListener() {
-
public void onClick(Widget sender) {
-
}
-
}
-
p.add(link);
-
RootPanel.get().add(p);
-
}
-
}
Deploying
At this point, you should actually be able to compile and deploy this very simple application. First you have to create build.properties in the project root and specify where the application should be deployed, for example
-
deploy.root=/pack/apache-tomcat-5.5.15/webapps/gwt
Then just execute the following:
ant deploy
And start tomcat. At this point, you should be able to access http://localhost:8080/gwt/dk.contix.gwt.Module/Module.html and see a link on a page. Pressing the link shouldn't do anything.
Adding a service
Now we want to implement a service and call it by clicking the link. First, define the new service:
-
package dk.contix.gwt.service;
-
-
/**
-
* Simple service implementation.
-
* @gwt.interface service="dk.contix.gwt.shared.ModuleService" path="/moduleService"
-
*/
-
public class ModuleServiceImpl extends RemoteServiceServlet {
-
-
/**
-
* @gwt.serviceMethod
-
*/
-
public String getDoubleText(String text) {
-
return text + text;
-
}
-
}
The service class should actually implement an interface, but we're going to generate it automaticaly. Do so by executing
-
ant generate
and refresh the project in Eclipse. At this point, dk.contix.gwt.shared should contain two new interfaces, ModuleService and ModuleServiceAsync. Also, a service factory has been created in dk.contix.gwt.client.
Modify the ModuleServiceImpl class so it implements ModuleService:
-
public class ModuleServiceImpl extends RemoteServiceServlet implements ModuleService {
Calling services
At this point, we're ready to call the remote service from the client. Modify the ClickListener:
-
Hyperlink link = new Hyperlink();
-
link.setText("Press me");
-
link.addClickListener(new ClickListener() {
-
public void onClick(Widget sender) {
-
ServiceFactory.getModuleService().getDoubleText("testing1", new AsyncCallback() {
-
public void onFailure(Throwable caught) {
-
p.add(new Label("Error: " + caught.toString()));
-
}
-
-
public void onSuccess(Object result) {
-
String t = (String)result;
-
p.add(new Label("Result: " + t));
-
}
-
});
-
}
-
}
Deploy the application again. Deploying will automatically generate a new web.xml with a servlet mapping the new service. After restarting Tomcat, you should be able to click the link and get a result back.
That's it
Yes, that's more or less it. The primary reason that it's so easy is the code generation, which means that
- Modules are automatically created, just annotate EntryPoint classed with @gwt.module
- Services are configured and interfaces are generated by annotating RemoteServiceServlet classes with @gwt.interface
- Remote methods are made available when they are annotated with @gwt.serviceMethod
- Access to the remote services goes through a ServiceFactory, which handles url mapping automatically.
For more complex applications, it's probably not necessary (or desirable) to generate web.xml, so just use it as a starting point. You'll probably add filters and other stuff later.
Have fun!




Thank you for the great write up about deploying GWT with ant.
The build.xml file references
ant-gwt.xml. Can you please post the contents of this file?Thanks,
Bryce