GWT Server Library - Reference Documentation v1.0

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 SL you can easily write Spring managed beans which act as GWT services, taking full advantage of both frameworks.

2.1. Quickstart

We'll briefly cover the steps necessary to publish a simple Spring managed bean so that a GWT client can communicate with it over RPC. There are several ways of exporting a bean to RPC, here we shall follow the simplest one, namely the GWTHandler. Details follow in Chapter 3.

We start off with the definition of the service interface. Our service will perform a simple arithmetic addition. Since the client application running in a browser will access this interface also (its Async version, to be precise), the service interface must extend GWT's RemoteService interface.

ServiceTest.java :

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

import com.google.gwt.user.client.rpc.RemoteService;

public interface ServiceTest extends RemoteService{
	public int add(int a, int b);
}

The implementation is free of any dependencies on Spring, GWT or the servlet API.

ServiceTestImpl.java :

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

import org.gwtwidgets.server.spring.test.server.ServiceTest;

public class ServiceTestImpl implements ServiceTest{
	public int add(int a, int b) {
		return a + b;
	}
}

This is a Spring application, so we load the Spring servlet which will export our service bean under the url http://localhost:8080/gwtWebApp/handler/rpctest

web.xml :

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app SYSTEM "web-app_2_3.dtd">
<web-app>
<!-- 
		Mapping an RPC service defined in handler-servlet.xml
-->
	<servlet>
		<servlet-name>handler</servlet-name>
		<servlet-class>
			org.springframework.web.servlet.DispatcherServlet  <!--  This is a Spring configuration-->
		</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>

	<servlet-mapping>
		<servlet-name>handler</servlet-name>
		<url-pattern>/handler/*</url-pattern>
	</servlet-mapping>

</web-app>

Last, we define a URL handler mapping like we'd do with any regular Spring MVC application, only that we won't use a SimpleUrlHandlerMapping but a GWTHandler which knows how to translate RPC calls to method invocations on POJOs.

handler-servlet.xml :

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
	<bean
		class="org.gwtwidgets.server.spring.GWTHandler"
		<property name="mappings">
			<map>
				<entry key="/rpctest" value-ref="RPCTest" />
			</map>
		</property>
	</bean>
	
	<bean id="RPCTest" class="org.gwtwidgets.server.spring.test.serverimpl.ServiceTestImpl" />
</beans>	

3. Publishing beans as RPC services

The 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 at runtime) automatically which delegates RPCs to method invocations to a specified 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.

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 SL or even a PHP backend that simulates the RPC protocol.

Without Spring and the SL, a regular RPC request is processed by GWT similar to this figure:

1.Browser encodes objects to RPC string
2.Browser makes HTTP request to the designated RPC URL on the server
3.Web server forwards the HTTP request to the web application which is bound to that URL
4.Based on the servlet mapping in web.xml the request is routed to the corresponding servlet
5.The RemoteServiceServlet decodes the RPC payload and invokes the service method
6.The service response is encoded as an RPC response payload and send as an HTTP response back to the browser
7.Browser decodes the RPC payload and invokes the service callback

Now, with Spring and the SL, there are a few more steps which are performed by the framework:

1.Browser encodes objects to RPC string
2.Browser makes HTTP request to the designated RPC URL on the server
3.Web server forwards the HTTP request to the web application which is bound to that URL
4.Based on the servlet mapping in web.xml the request is routed to the corresponding servlet
5.Spring routes the request based on its mapping (i.e. the SimpleUrlHandlerMapping) to the corresponding controller
5.1SL's GWTRPCServiceExporter decodes the RPC request into Java objects
5.2The GWTRPCServiceExporter forwards the request to a specified service bean
5.3The GWTRPCServiceExporter encodes the service bean's response into an RPC payload
6.Spring sends the response back to the servlet container and back to the Browser
7.Browser decodes the RPC payload and invokes the service callback

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).

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" />

Annotations can also be used to publish services to URLs. Beans in the current application context featuring the GWTRequestMapping annotation on their service interface will be picked up by the GWTHandler and mapped to the specified URL. Please note that the URL is relative to URL which the GWTHandler is already servicing:

<beans>
	<bean class="org.gwtwidgets.server.spring.GWTHandler"/>

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

</beans>
@GWTRequestMapping("/service")
public interface AnnotatedService extends ServiceTest{

}

You can optionally export annotated beans from a parent application context by enabling the scanParentApplicationContext property.

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 it 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 which may be of interest to Gilead users as it allows services to be wrapped with a GileadRPCServiceExporter instead of the plain RPCServiceExporter. For further details please consult 4.3 Using Gilead.

3.3 Extending a base class - GWTSpringController

The GWTSpringController is the SL's oldest yet best-performing approach towards integrating GWT with Spring and it requires an RPC service to extend 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 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 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 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 Gilead (Hibernate4GWT)

Gilead is a library that moves Hibernate managed objects via RPC between a GWT client and a server. The SL incorporates Gilead via the GileadRPCServiceExporter which can be used similar to the GWTRPCServiceExporter. With regard to domain objects, Gilead supports two modes of operation: the light entity mode where domain objects need to extend the LightEntity class and the dynamic proxy mode. For serveral reasons, you are strongly advised to stick with the light entity mode, though dynamic proxy mode is possible (more on that later).

4.3.1 Light Entity Mode

A simple setup which uses the GileadRPCServiceExporter 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 Gilead POJO stateless pojo store. Based on what you want to do, you may need
a different implementation.
 -->
<bean id="PojoStore" class="net.sf.gilead.core.store.stateless.StatelessProxyStore" />
 
<!--
Gilead's Hibernate Utilities
 -->
<bean id="HibernateUtil" class="net.sf.gilead.core.hibernate.HibernateUtil">
	<property name="sessionFactory" ref="SessionFactory"/>
</bean>


<!--
Gilead's HibernateBeanManager binds the POJO store with a Hibernate session factory.
 -->
<bean id="HibernateBeanManager" class="net.sf.gilead.core.PersistentBeanManager">
	<property name="pojoStore" ref="PojoStore" />
	<property name="persistenceUtil" ref="HibernateUtil" />
</bean>

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

<bean id="GileadRPCService" class="org.gwtwidgets.server.spring.gilead.GileadRPCServiceExporter">
	<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>
	

The same example, this time with annotated services and the GWTHandler:

	<!--
	GWTHandler will scan the application context for beans with the GWTRequestMapping annotation 
	-->
	<bean
		class="org.gwtwidgets.server.spring.GWTHandler">
	<!--
	Note that the GWTHandler will not wrap services with a regular GWTRPCServiceExporter but
	with a GileadRPCServiceExporter - or with whatever you tell it to. 
	-->
		<property name="serviceExporterFactory">
			<bean class="org.gwtwidgets.server.spring.gilead.GileadRPCServiceExporterFactory">
				<property name="beanManager" ref="HibernateBeanManager"/>
			</bean>
		</property>
	</bean>

	<!--
	A service bean which uses hibernate. Its service interface carries the GWTRequestMapping annotation.	
	 -->
	<bean id="HibernateDomainService" class="org.gwtwidgets.server.spring.test.serverimpl.HibernateDomainServiceImpl">
		<property name="sessionFactory" ref="SessionFactory"/>		
	</bean>

	<bean id="PojoStore"
		class="net.sf.gilead.core.store.stateless.StatelessProxyStore"/>
	
	<bean id="HibernateUtil"
		class="net.sf.gilead.core.hibernate.HibernateUtil">
		<property name="sessionFactory" ref="SessionFactory"/>
	</bean>

	<bean id="HibernateBeanManager"
		class="net.sf.gilead.core.PersistentBeanManager">
		<property name="proxyStore" ref="PojoStore" />
		<property name="persistenceUtil" ref="HibernateUtil"/>
	</bean>

	<bean id="SessionFactory"
		class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
		...
	</bean>
	
...	
	

Note that for a fully functional setup transaction support should be added to the service beans. For complete examples consult gilead-servlet.xml and gileadannotated-servlet.xml from the test package.

4.3.2 Dynamic Proxy Mode

Dynamic proxy mode for domain objects has some prerequisites:

IsSerializable is mandatory: Domain objects must implement IsSerializable. Implementing Serializable won't do.

No serialization policy file: You cannot have any serialization policy. Delete the generated serialization policy prior to deploying. A consequence of the missing serialization policy is that any DTOs or Exceptions must implement IsSerializable.

Generator: The *.gwt.xml module must reference Gilead's generator:

	<generate-with class="net.sf.gilead.proxy.gwt.Gwt15ProxyGenerator">
		<when-type-assignable class="com.google.gwt.user.client.rpc.IsSerializable" />
	</generate-with>

GWT.create: You have to use GWT.create(DomainClass.class) instead of new DomainClass() when creating instances of Hibernate managed objects on the client side.

ProxyClassMapper: You need to use the ProxyClassMapper and tell the GileadRPCServiceExporter to use it.

	<bean id="ClassMapper" class="net.sf.gilead.core.beanlib.mapper.ProxyClassMapper">	
		<property name="persistenceUtil" ref="HibernateUtil"/>
		<property name="java5" value="true"/>
	</bean>

	<bean id="HibernateBeanManager"
		class="net.sf.gilead.core.PersistentBeanManager">
		<property name="proxyStore" ref="PojoStore" />
		<property name="persistenceUtil" ref="HibernateUtil"/>
		<property name="classMapper" ref="ClassMapper"/>
	</bean>

	<bean id="GileadDomainService" class="org.gwtwidgets.server.spring.gilead.GileadRPCServiceExporter">
		<property name="beanManager" ref="HibernateBeanManager" />
		<property name="service" ref="HibernateDomainService" />
		<property name="usingProxyClassLoader" value="true"/>
	</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. The 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 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.

I am getting a NullPointerException in GenericServlet

Don't export services in the application context, always export them in a -servlet.xml file. GWT's RPC mechanism expects a servlet environment into which it logs information. The application context does not provide this environment (namely the serlvet configuration), which causes GWTRPCServiceExporter instances declared in the application context to lack the servlet configuration and thus procude NPEs.

I am getting something about SomeClass_gilead_15 and serialization policy

In short: make sure you have read Chapter 4.3.

Some background: The GWT compiler needs to generate wrapper classes for every DTO class managed by Gilead. For the client, these classes are generated by the GWT compiler as part of the Javascript output and for the server they are generated as Java bytecode when the application starts. Currently there is a mismatch between Gilead and GWT when dynamic proxy mode is used, as a result of which the GWT compiler does not generate all the necessary code to handle these classes. The only known workaround is to switch to light entity mode. If you are interested in resolving this issue, please consider voting for issue 3849.

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. Gilead homepage http://noon.gilead.free.fr/gilead/
7. Hibernate4GWT project homepage http://hibernate4gwt.sourceforge.net/