Skip navigation.
Home

GWT Server Library - Reference Documentation v0.1.5


GWT Server Library - Reference Documentation v0.1.5

1. Table of Contents

2. General Overview

The GWT Server Library is a collection of Java server side components for the Google Web Toolkit AJAX framework
with the current focus on the Spring framework by facilitating publishing of Spring beans as RPC services. The main
binary dependencies are GWT 1.5, Spring 2.5 and Commons Logging 1.1.

The Spring Framework is an established component framework for web applications that span
authentication, database access and complex page flow. Through its aspect oriented approach
it is unobtrusive and cleanly separates the presentation layer from the business logic and
the data model, allowing for back end services which are agnostic towards the way the
presentation is rendered. This is the ideal base for a GWT application, which also separates the
presentation (widgets that run in the browser) from the business logic (RPC services
running on the web server) from the data model (the objects serialised over RPC).

GWT binds java methods to RPC calls by using the Servlet API so that
each service you write is a servlet. The Servlet API however is rather crude and the servlet
container (like Tomcat) is a gross environment providing little assistance to elaborate tasks
like transaction management, AOP tasks (authentication, logging, per-task caching) etc. Also
the notoriously scarce configuration abilities are by far inferior to Spring's XML
configuration and bean injection which allows even the most complex configurations by
plugging objects together in XML. With the GWT-SL you can easily write Spring managed beans
which act as GWT services, taking full advantage of both frameworks.

3. Publishing beans as RPC services

The GWT-SL creates RPC services following different implementation strategies, from extending a base
class similar to the default way services are created in GWT to publishing POJOs as services without
dependencies on any class, interface or even annotation. It is common to all approaches that eventually
a RemoteServiceServlet is generated (usually in runtime) automatically which delegates
RPCs to method invocations to the provided service bean. The following sections describe the different
approaches towards creating services which can be used alone or together.

There are always three common steps and you always need a service interface, an asynchronous callback version
of that interface and a service implementation.

  • Create the service interface A, the RemoteService and AsyncCallback interfaces from the service interface
  • Create a service implementation of A
  • Use one of the RPC publishing methods to expose your service implementation

Note that nothing changes on the client, regardless of which way you use to expose a service to RPC.
The client does not notice whether you use plain GWT, the GWT-SL or even a PHP backend that simulates the RPC
protocol.

3.1 Publishing POJOs as services - GWTRPCServiceExporter

The GWTRPCServiceExporter is the purist's take at developing services since it does not introduce any API and compile
time dependency to your service. Essentially it is a wrapper which exports any POJO as an RPC service. In order for the
GWTRPCServiceExporter to know which methods to bind to RPC, the service bean should either implement a RemoteService
interface or you should provide it in the configuration. If no interface is specified, all methods are published to RPC
which should be avoided - even fundamental methods like wait() can provide backdoors for various denial of service
attacks.

Let's create a simple bean which we will later publish as a service. This example is taken from the unit
test web application and it shows a trivial bean with a method that adds two integers. Note that
the bean is really a POJO, it does not extend or implement any class or interface.

package org.gwtwidgets.server.spring.test.serverimpl;
public class ServiceTestPOJO {

	public int add(int a, int b) {
		return a + b;
	}
...
}	

Next we need an interface which extends RemoteService and declares the methods which should be exposed
to RPC. Since in our example we have only one, this is an easy task:

package org.gwtwidgets.server.spring.test.server;

public interface ServiceTest extends RemoteService{

public int add(int a, int b);

}

That leaves only the correct bean creation and URL mapping in the Spring servlet XML:


<!-- 
	Create POJO version of the Test service: implements only methods but does not expose any RPC interfaces 
-->

<bean id="ServiceTestPOJO" class="org.gwtwidgets.server.spring.test.serverimpl.ServiceTestPOJO" />


<!-- 
	Declaration of RPC service with the RPCServiceExporter which behaves very similar to 
	a Spring controller and needs to be mapped to URLs the same way any other Spring 
	controller is mapped...
-->

<bean id="RPCTestPOJO" class="org.gwtwidgets.server.spring.GWTRPCServiceExporter">

<!--
	Reference to the service bean which should be exported via RPC to the web.
-->

	<property name="service" ref="ServiceTestPOJO" />

<!--
	If our Test service was not a 100% pure POJO but also implemented the ServiceTest interface then
	we wouldn't have to specify it here. Note that you can provide multiple interface names, as long as
	your service has the corresponding methods with a matching signature.
-->

	<property name="serviceInterfaces">
		<value>
			org.gwtwidgets.server.spring.test.server.ServiceTest
		</value>
	</property>
</bean>


<!--
	... with a SimpleUrlHandlerMapping for instance:
-->

<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
	<property name="mappings">
		<map>
			<entry key="/service" value-ref="RPCTestPOJO" />
		</map>
	</property>
</bean>

3.2 Publishing multiple beans - GWTHandler

The GWTHandler allows you to quickly map multiple RPC service beans to different URLs
very similar to the way Spring's SimpleUrlHandlerMapping maps URLs to controllers. The
mapped beans are internally wrapped into GWTRPCServiceExporter
instances, with the notable difference that you cannot specify a service interface in the configuration
and the service beans must implement the RemoteService interface (as a matter of fact there is
a workaround even for that by providing your own implementation of a RPCServiceExporter -
interested readers please consult the javadocs for GWTHandler).

First we need the service interface from our previous example:

package org.gwtwidgets.server.spring.test.server;

public interface ServiceAdd extends RemoteService{

public int add(int a, int b);

}

And the corresponding implementation:

package org.gwtwidgets.server.spring.test.serverimpl;

public class ServiceAddImpl implements ServiceAdd{
	public int add(int a, int b) {
		return a + b;
	}

}

Finally the mapping:

<bean id="urlMapping" class="org.gwtwidgets.server.spring.GWTHandler">

<!-- Supply here mappings between URLs and services. Services must implement the RemoteService interface but
are not otherwise restricted.-->
	<property name="mappings">
		<map>
		
<!-- Other mappings could follow -->
			<entry key="/add.rpc" value-ref="ServiceAdd" />
		</map>
	</property>
</bean>

<!-- Declare service -->
<bean id="ServiceAdd" class="org.gwtwidgets.server.spring.test.serverimpl.ServiceAddImpl" />

A sidenote on method interceptors and AOP advice: advice applied on the GWTHandler is
applied on the servlet request/response level and not the method invocation level of a particular service.
In this case is is applied before/after/around the RPC request handling and not around the service method
invocation. You should carefully distinguish between advice applied on the GWTHandler (i.e. access
authorisation based on session attributes) and advice applied on services (i.e. logging or transaction management).

If you require a different functionality (for example with exception translation) to be
wrapped around your services than the one provided by the default GWTRPCServiceExporter which is used
by the GWTHandler you can inject your own implementation of a RPCServiceExporter by providing
a RPCServiceExporterFactory.

3.3 Extending a base class - GWTSpringController

The GWTSpringController is GWT-SL's oldest yet best-performing approach towards integrating GWT with Spring
and it requires an RPC service to extends the org.gwtwidgets.server.spring.GWTSpringController class.
While you are usually better off with any of the previous strategies, the GWTSpringController is lighter
than the other implementations, relies less on reflection and consumes less processing time.

The service extends GWTSpringController:

package org.gwtwidgets.server.spring.test.serverimpl;

public class ControllerAdd extends GWTSpringController implements ServiceAdd{

	public int add(int a, int b) {
		return a+b;
	}

}

And the mapping:

<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
	<property name="mappings">
		<map>
			<entry key="/add.rpc" value-ref="ControllerAdd" />
		</map>
	</property>
</bean>

<bean id="ControllerAdd" class="org.gwtwidgets.server.spring.test.serverimpl.ControllerAdd"/>

4. How to

In this chapter we will discuss common cases in a Spring web application and how the GWT-SL
deals with them - yet, since it uses the basic Spring building blocks and conventions we hope
that you will find little surprises and hardly any unexpected behaviour.

4.1 Exception translation

The term Exception translation in general refers to the task of converting one exception
instance to an other of a different class as the program execution passes through different application
layers which nest the original exception in an exception relevant to the current layer. Exceptions
are usually nested so that the root cause lies deep in the stack trace while the exception at the
bottom of the stack trace is an entirely different one, generated by the various program layers the
method invocation went through.

By default the GWTHandler and the GWTRPCServiceExporter unwrap the immediate root
cause of any exception and propagate it back to the client.
In this regard they behave slightly different from previous versions which would propagate the first
SerializableException found in the stack trace to the client, regardless how deep in the
stack trace it was.

Exception translation is important for RPC services because only SerializableExceptions are
propagated through the RPC protocol back to the client and all other exceptions will usually result in
terminating the current request with the client not getting any meaningful message. In previous versions
you could switch off exception translation, now this it possible by overriding methods in the
GWTRPCServiceExporter.

SerializableException is a checked exception and as such it does not cause
transactions in the exception-throwing service to be rolled back. This is best tackled either from
inside the service implementation (since you may want the transaction to be committed) or by declaring
the conditions under which a transaction should be rolled back by the transaction proxy - for details on
how to attain both please consult the
Spring Reference Manual.

In v0.1.4c the GWTRPCServiceExporter was refactored to move exception handling into
separate methods. By extending GWTRPCServiceExporter and overriding these methods you can
influence substantially the way target services are invoked and the way exceptions are handled.

For instance, imagine that you are trying to handle exceptions in your Spring applications in a common way.
You want to catch all exceptions before they reach the console (or the user), possibly filter out the long traces that
are often introduced by runtime class weaving (such as with CGLIB), filter out InvocationTargetException
traces which are appended to exceptions during reflective invocation and want to repackage these exceptions
into other, more friendly and application specific exceptions. You would do that with the Spring AOP or a
MethodInterceptor, catch there any exceptions, inspect them and throw new exceptions.

The exceptions you throw from within the advice would be RuntimeExceptions, because they cause
Springs transaction management to roll-back by default any transactions and because they do not violate the
signature of the invoked method. If the last statement looks puzzling, think of this scenario:

class MathService {

	public double divide(double a, double b){
		return a / b;
	}
}

And an obvious advice:


class DivisionByZero extends Exception{
}

class MathAdvice {

	public Object doAround(Object target, Method method, Object[] args){
		double b = (double)args[1];
		if (b == null) throw new DivisionByZeroException();
		return method.invoke(target, args);
	}
}

This means trouble: although you have a MathService instance at hand (more precicely, an advised
proxy - but that is not the invoker's concern), calling divide(3,0) will throw a checked
exception, namely DivisionByZero. If DivisionByZero was a RuntimeException
the call would be fine, but now divide's method signature contract is violated. Because the JVM
will not allow that, it will wrap the exception into an
UndeclaredThrowableException
which is a RuntimeException and does not violate the method signature when thrown. But you may have
your reasons for throwing checked exceptions (i.e. because you don't want a transaction to be rolled back) the
GWTRPCServiceExporter can be overridden to handle exceptions. The particular case discussed can be
tackled by catching an UndeclaredThrowableException and propagating the enclosed exception to the
client :

public class MyGWTRPCServiceExporter extends GWTRPCServiceExporter{

	@Override
	protected String handleUndeclaredThrowableException(Exception e, Method targetMethod, RPCRequest rpcRequest)
			throws Exception {
		Throwable cause = e.getCause();
		String failurePayload = RPC.encodeResponseForFailure(rpcRequest.getMethod(), cause);
		return failurePayload;
	}

}

4.2 Accessing the Servlet API from inside a service

While not 100% in tune with the MVC pattern, it is often convenient to access the servlet
container, the HTTP session or the current HTTP request from the business layer. The GWT-SL
provides several strategies to achieve this which pose a compromise in the amount of configuration
required to set up and the class dependencies introduced to the business code.

The easiest way to obtain the current HTTP request is by using the ServletUtils class
which provides convenience methods for accessing the HttpServletRequest and
HttpServletResponse instances. Please note that it makes use of thread local variables
and will obviously not return correct values if used in any other than the invoking thread.

A simple example:

package org.gwtwidgets.server.spring.test.serverimpl;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.gwtwidgets.server.spring.ServletUtils;

public class ServiceTestPOJO {

...
	public String replaceAttribute(String name, String value) {
		HttpSession session = ServletUtils.getRequest().getSession(true)
		String oldValue = (String) session.getAttribute(name);
		session.setAttribute(name, value);
		return oldValue;
	}


}

It is also possible to inject the request/response pair in an IoC manner, when compile-time
dependency on the GWT-SL API is not desired. This approach sets the request and response to the service
as a thread local variable. Thus, the service implementation could look similar to:

package org.gwtwidgets.server.spring.test.serverimpl;

public class ServiceHttpRequestTestPOJOImpl{

	private static ThreadLocal<HttpServletRequest> servletRequest = new ThreadLocal<HttpServletRequest>();

	private static ThreadLocal<HttpServletResponse> servletResponse = new ThreadLocal<HttpServletResponse>();

...

// These two setters...
	public void setRequest(HttpServletRequest request) {
		servletRequest.set(request);
	}
	
// ... must be public
	public void setResponse(HttpServletResponse request) {
		servletResponse.set(request);
	}

	protected HttpServletRequest getRequest() {
		return servletRequest.get();
	}

// That's a service method exposed to RPC
	public String test2(String newValue) {
		HttpSession session = getRequest().getSession();
		return (String) session.getAttribute(attrName);
	}

}

Now we have to create the bean that will perform the actual injection of the servlet request and response
and glue it to the service:

<!-- Target service bean -->
<bean id="ServiceTestHTTPTarget" class="org.gwtwidgets.server.spring.test.serverimpl.ServiceHttpRequestTestImpl" />

<!-- Create request setter -->

<bean id="requestSetter" class="org.gwtwidgets.server.spring.RequestInjection">
	<property name="requestSetterName" value="setRequest"/>
	<property name="responseSetterName" value="setResponse"/>
</bean>

<!-- Create Servlet API aware service -->
<bean id="ServiceTestHTTP" class="org.springframework.aop.framework.ProxyFactoryBean">
	<property name="target" ref="ServiceTestHTTPTarget"/>
	<property name="autodetectInterfaces" value="true"/>
	<property name="interceptorNames">
		<list>
			<value>requestSetter</value>
		</list>
	</property>
</bean>

4.3 Using Hibernate4GWT

Hibernate4GWT is a servlet that moves
Hibernate managed objects via RPC between a GWT client and a server. As of Hibernate4GWT
v1.0 the SL has the HB4GWTRPCServiceExporter which is an adaption of
HibernateRemoteService and can be used similar to the GWTRPCServiceExporter.
For information on how to setup, please refer to the Hibernate4GWT
overview.

A simple setup looks like this:

<!--
That's the business service which returns and or accepts Hibernate managed objects.
 -->
<bean id="HibernateDomainService" class="org.gwtwidgets.server.spring.test.serverimpl.HibernateDomainServiceImpl">
	<property name="sessionFactory" ref="SessionFactory"/>		
</bean>

<!--
The hibernate4gwt POJO stateless pojo store. Based on what you want to do, you may need
a different implementation.
 -->
<bean id="PojoStore" class="net.sf.hibernate4gwt.core.store.stateless.StatelessPojoStore" />

<!--
hibernate4gwt's HibernateBeanManager binds the POJO store with a Hibernate session factory.
 -->

<bean id="HibernateBeanManager" class="net.sf.hibernate4gwt.core.HibernateBeanManager">
	<property name="pojoStore" ref="PojoStore" />
	<property name="sessionFactory" ref="SessionFactory" />
</bean>

<!--
The SL's HB4GWTRPCServiceExporter combines hibernate4gwt's HibernateBeanManager with the
business service and exports it's facade via RPC.
-->

<bean id="HB4GWTRPCService" class="org.gwtwidgets.server.spring.hb4gwt.HB4GWTRPCServiceExporter">
	<property name="beanManager" ref="HibernateBeanManager" />
	<property name="service" ref="HibernateDomainService" />
</bean>

<!--
This is a simple Spring managed Hibernate session factory.
 -->
 
<bean id="SessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
	...
</bean>
	

4.4 HTTP Headers

Tweaking HTTP headers is a useful technique when it comes to performance tuning your GWT application. The SL
contains the ResponseHeaderFilter which is a servlet filter used to alter response headers.
It was inspired by an article
written by Jason Falkner which discusses many interesting applications of HTTP headers.

init-param entries for the ResponseHeaderFilter are HTTP header names and values and are not further interpreted,
except for the special parameter ResponseHeaderFilter.UrlPattern which can be used to specify a regular expression which,
when specified, applies headers only to the subset of request URLs which match the provided pattern.

Some HTTP headers describe the validity period of a web resource and can be used to enable caching of resources in a browser.
In an GWT application this will usually be the .cache.html, the module entry HTML page, CSS and images.

To enable caching for a resource, something along the lines of

<filter>
	<filter-name>CachingFilter</filter-name>
	<filter-class>org.gwtwidgets.server.filters.ResponseHeaderFilter</filter-class>
	<init-param>
		<param-name>Expires</param-name>
		<param-value>Sun, 17 Jan 2038 19:14:07 GMT</param-value>
	</init-param>
</filter>

could be used in web.xml

A further interesting application is compressing of static resources such as scripts and static HTML pages. These do not have to be
compressed again for every request but can reside in an already compressed format on the file system. It then suffices to add the appropriate
headers to the HTTP response in order to instruct the browser to inflate the transmitted resource:

<filter>
	<filter-name>GzipFilter</filter-name>
	<filter-class>org.gwtwidgets.server.filters.ResponseHeaderFilter</filter-class>
	<init-param>
		<param-name>Content-Type</param-name>
		<param-value>text/html; charset=utf-8</param-value>
	</init-param>
	<init-param>
		<param-name>Content-Encoding</param-name>
		<param-value>gzip</param-value>
	</init-param>
	<init-param>
		<param-name>ResponseHeaderFilter.UrlPattern</param-name>
		<param-value>.*?\.html</param-value> <!-- Match only *.html URLs -->
	</init-param>
</filter>

5. FAQ

I am seeing a java.lang.NoClassDefFoundError although the class/jar is there!

The most common cause of this error is that not all related classes are loaded by the same class loader. If, for example, the spring library,
GWT, CGLib and your project classes are partially deployed in WEB-INF/lib and common/lib a NoClassDefFoundError may be thrown.
This is a configuration detail of the concrete servlet container you are using and is often solved by placing all libraries into the same location,
though that may not always be easy because of your web server's dependencies. A very good overview of how class loading is dealt with can be read
at the Commons Logging project site.

I am getting a java.lang.reflect.InvocationTargetException

InvocationTargetExceptions are envelopes that contain other exceptions - it occurs when an exception is thrown in a method
which is invoked via reflection and it is the most common exception you will see when your GWT services throw unintentionally an exception.
This is because RPC joins object methods with HTTP requests by relying on method invocation through reflection. The true cause of the exception
then lies deeper in the stack trace and is nested inside the InvocationTargetException. You may also want to read up on
Exception Translation which discusses the special case of not treating SerializableExceptions
as exceptions but propagating them properly back to the client.

My application runs on a 1.4 JRE and I'm getting a ClassFormatError

Since 0.1.5 the SL requires Java 1.5. If you have to use Java 1.4, consider using a 0.1.4 release of the SL which
includes Java 1.4 support. For this, please consult the corresponding documentation in the 0.1.4 SL.

RPCs to my services don't work, I'm getting a 404 but no exception in the server log

If you can rule out any other errors and you are not seeing any exceptions in the server log (let's supposed that logs are working
OK) your URL mappings may be incorrect. GWT-SL hosts multiple RPC services under one or more Spring managed servlets, thus a good
start is to check the URL mappings in web.xml:

<servlet>
	<servlet-name>myRPCServices</servlet-name>
	<servlet-class>
		org.springframework.web.servlet.DispatcherServlet
	</servlet-class>
	<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
	<servlet-name>myRPCServices</servlet-name>
	<url-pattern>/myRPCServicesURL/*</url-pattern>
</servlet-mapping>

This maps /myRPCServicesURL/... to a spring servlet which is defined in myRPCServices-servlet.xml.
Note that the /myRPCServicesURL part of the URL is already 'consumed' by the servlet container and you should not duplicate it in
the subsequent Spring mappings:

<bean id="urlMapping" class="org.gwtwidgets.server.spring.GWTHandler">
<property name="mappings">
	<map>
		<-- Attention: We don't repeat the servlet URL, so it's not /myRPCServicesURL/service1 but just /service1 -->
		<entry key="/service1" value-ref="FirstServiceBean" />
		<entry key="/service2" value-ref="SecondServiceBean" />
		<entry key="/service3" value-ref="ThirdServiceBean" />
		...
	</map>
</property>
</bean>

How do I run the unit tests?

Very basic stand-alone unit test can be run with ant test. In order to run the demo unit test web application,
first compile it with ant war and deploy it to a servlet container, it is then accessible under http://myServer:port/gwt-sl.
It runs a series of automated tests and should conclude with 'Finished tests' and no error messages.

Why does my project not run with the hosted mode browser?

The short answer: understand and use the hosted browser's -noserver option.

Some background: The embedded tomcat server that comes with the hosted mode browser is intended as a simple aid
when making your first steps with GWT, so that you can focus on client development and so that you do not
have to worry about server configuration. An applications's ability to run with the hosted mode browser is not
affected by the GWT-SL, simply because the SL is a server side framework, while the browser runs the client
side portion of the application code.
Where problems do occur is when you run the browser together with the embedded tomcat server: your application
requires Spring and a mapping of URLs to the RPC services to be set up, but the embedded tomcat starts with
its own configuration instead of yours. Hence it is simpler to setup your own development server, as
you would do with every traditional web application and treat the GWT compiler output as a bunch of static
resources. For an example of such a setup run the package task of build.xml and
inspect the contents of the target/webapp directory or check the equivalent demo WAR in the
project's download area (sources are in src/test).

RPCs are always returning the same objects to the client

An RPC is nothing but an HTTP request to the server - depending on the HTTP headers returned by the server's response
it can happen that the browser decides that the response can be cached. This means that future similar requests (with the same URL)
may be served from the browser's cache. The best way to avoid caching RPC responses is by modifying the HTTP headers of the response
in such a way that browser caching is disabled - for an example of how to do this consult the HTTP Headers chapter.
An alternative solution is to make sure that each request is dispatched to an unique URL, i.e. by appending to each RPC request a parameter
with a random, unique value.

Also note that the SL's RPC implementations (see chapter 3) attempt to disable response caching by default.

6. Links and Resources

1. Project homepage http://gwt-widget.sourceforge.net/

2. User group http://groups.google.com/group/gwt-sl/topics

3. Spring project homepage http://springframework.org/

4. Hibernate project homepage http://hibernate.org/

5. GWT homepage http://code.google.com/webtoolkit/

6. Hibernate4GWT project homepage http://hibernate4gwt.sourceforge.net/