GWT: Google Web Toolkit: Difference between revisions

From Elvanör's Technical Wiki
Jump to navigation Jump to search
No edit summary
mNo edit summary
 
(13 intermediate revisions by the same user not shown)
Line 1: Line 1:
This page collects various information about GWT programming.
This page collects various information about GWT programming.


== GWT configuration files: the GWT XML modules ==
= GWT configuration files: the GWT XML modules =


Configuration files in GWT are called modules. In a module, you may specify (among other things):
Configuration files in GWT are called modules. In a module, you may specify (among other things):
Line 14: Line 14:
'''Warning:''' be careful when inheriting modules. If the inherited module has a entry point class defined, it *will* get instantiated, even if your own module already has one. This can lead to confusion. If you just want to use the source from another package structure, use the <tt><source></tt> element.
'''Warning:''' be careful when inheriting modules. If the inherited module has a entry point class defined, it *will* get instantiated, even if your own module already has one. This can lead to confusion. If you just want to use the source from another package structure, use the <tt><source></tt> element.


== Java exceptions in the server side code ==
'''Update:''' I cannot seem to get the <tt><source></tt> element to work correctly with a different package (eg, include something from com.example in net.example). So you do need to inherit from a specially written module, located on the proper package, and containing only a <source> element, not <entry-point> or stuff like that.
 
* The public entry in a GWT module supports Ant's file set mechanism, thus allowing you to control precisely what needs to be copied.
 
* Note that module files are not needed at all for deployment/production. They are only needed for the build system. They should not be present on the servlet container.
 
= Java exceptions in the server side code =


They need to implement IsSerializable. You must thus specify on your server code that the function throws <tt>SerializableException</tt> and not just <tt>Exception</tt>.
They need to implement IsSerializable. You must thus specify on your server code that the function throws <tt>SerializableException</tt> and not just <tt>Exception</tt>.
Line 30: Line 36:
</pre>
</pre>


== GWT automatic serialization ==
= GWT automatic serialization =
 
* Do '''not''' forget that every class that you want to serialize must implement the <tt>IsSerializable</tt> Google interface.


* Be careful that GWT automatic serialization, especially for collections, can be tricky. You must specify in your Java source code what your collections contain. Maybe with Java 1.5 the situation will improve.
* Be careful that GWT automatic serialization, especially for collections, can be tricky. You must specify in your Java source code what your collections contain. Maybe with Java 1.5 the situation will improve.


* Besides, if you use Hibernate, Hibernate will fill your beans (objects) with its own implementations for collections (eg it will not use the implementations from java.util, but for a set will use org.hibernate.PersistentSet). Currently (as of GWT 1.3) there are several solutions available.
* Besides, if you use Hibernate, Hibernate will fill your beans (objects) with its own implementations for collections (eg it will not use the implementations from java.util, but for a set will use org.hibernate.PersistentSet). Currently (as of GWT 1.3) there are several solutions available:
** Do a mapping between the Hibernate beans and the GWT client beans (apparently this can be somewhat automated by using Dozer).
** Do a mapping between the Hibernate beans and the GWT client beans (apparently this can be somewhat automated by using Dozer).


== GWT Client Widgets ==
= GWT Client Widgets =


* StackPanel: If you apply a style (CSS) to this panel, it will actually be applied to the "panel in itself", NOT to the header (title) of the panel. If you wish to apply a CSS style to the header, enter the header directly as HTML code.
* StackPanel: If you apply a style (CSS) to this panel, it will actually be applied to the "panel in itself", NOT to the header (title) of the panel. If you wish to apply a CSS style to the header, enter the header directly as HTML code.


== GWT & CSS ==
= GWT & CSS =


There is no default CSS style. The classes defined for the GWT widgets can be used in your own CSS file, but it is not mandatory to add a CSS file for a GWT page to work.
There is no default CSS style. The classes defined for the GWT widgets can be used in your own CSS file, but it is not mandatory to add a CSS file for a GWT page to work.


== GWT Tools ==
= GWT & Tomcat =
 
* The gwt-servlet.jar file needs to be put in the WEB-INF/lib directory of your webapp. It cannot be put in the shared/lib directory of Tomcat. Some things will work but serialization across RPCs won't.
* URLs for accessing servlets must be of the form GWT.getModuleBaseURL() + "YourServletName". I believe GWT.getModuleBaseURL() returns the name of the webapp.
 
= GWT & Hosted Mode =
 
If you use hosted mode, a directory named "tomcat/" is created when running GWTShell (but nothing from your source directory seems to be copied there).
 
* To get the URL/servlet mapping working, you must add the <tt><servlet></tt> element to your GWT XML module.
* Note that by himself, the GWTShell program will NOT compile your Java code. You must manually compile your server-side Java-code (via Ant) and specify the location of the built classes on the Java classpath when lauching GWTShell.
* However the '''client side''' code seems to be automatically translated to JavaScript.
* Since Google only ships a 32 bit version of GWT on Linux, you must switch to a 32 bit Java environment on Gentoo amd64 when running in Hosted Mode. Eg:
GENTOO_VM="emul-linux-x86-java-1.5" java -cp "$APPDIR/src:$APPDIR/build/WEB-INF/classes:/opt/gwt/gwt-user.jar:/opt/gwt/gwt-dev-linux.jar"
    com.google.gwt.dev.GWTShell
* The syntax for the URLs in the Hosted Mode browser is "module_name/html_file.html".
* You can run hosted mode in a different directory than the default one (root). Just adapt the Bash script loading Hosted Mode, like this:
 
APPDIR=`pwd`/`dirname $0`;
cd $APPDIR/build/hosted;
 
* The best to run Hosted Mode is to dump altogether the original bash script and create your own Ant task.
 
* '''Warning:''' the patterns on the public XML node of a GWT module also applies to the Hosted Mode in the integrated Tomcat container. This means that anything you specify in the excludes, for example, will not be accessible to the Tomcat container in hosted mode.
 
= GWT Tools =


Since you cannot really see the HTML source before it is created via the JavaScript, the Firefox add-on '''Firebug''' is really, really helpful with GWT.
Since you cannot really see the HTML source before it is created via the JavaScript, the Firefox add-on '''Firebug''' is really, really helpful with GWT.


== GWT Problems ==
= Debugging =
 
* If you encounter a problem in hosted mode with a RPC, which *seems* to be working on web mode, make sure that your callback object is correct. You would encounter an error message of the type:
 
java.lang.NullPointerException: null
at net.elvanor.client.QueryServices_Proxy$1.onCompletionImpl(transient source for net.elvanor.client.QueryServices_Proxy:69)
 
Note that the remote call would still take place; however it would not complete.
 
= GWT Problems =


* Currently GWT cannot produce pages working correctly when parsed through Firefox XHTML engine. This means that you absolutely need to avoid *.xhtml files or anything that the web server will serve as XML content to Firefox.
* Currently GWT cannot produce pages working correctly when parsed through Firefox XHTML engine. This means that you absolutely need to avoid *.xhtml files or anything that the web server will serve as XML content to Firefox.

Latest revision as of 17:50, 29 July 2013

This page collects various information about GWT programming.

GWT configuration files: the GWT XML modules

Configuration files in GWT are called modules. In a module, you may specify (among other things):

  • an entry point class (this class will be instantiated when the module will be read from the base HTML file and the gwt.js script);
  • some source path (this will be translated to JavaScript by the GWT compiler);
  • a public path (files on this directory will be copied to the deployment server);
  • some CSS or native JavaScript files to be injected into the GWT code.

You can also inherit other GWT modules from one module. This is equivalent to copy all the contents of the inherited module into the current module.

Warning: be careful when inheriting modules. If the inherited module has a entry point class defined, it *will* get instantiated, even if your own module already has one. This can lead to confusion. If you just want to use the source from another package structure, use the <source> element.

Update: I cannot seem to get the <source> element to work correctly with a different package (eg, include something from com.example in net.example). So you do need to inherit from a specially written module, located on the proper package, and containing only a <source> element, not <entry-point> or stuff like that.

  • The public entry in a GWT module supports Ant's file set mechanism, thus allowing you to control precisely what needs to be copied.
  • Note that module files are not needed at all for deployment/production. They are only needed for the build system. They should not be present on the servlet container.

Java exceptions in the server side code

They need to implement IsSerializable. You must thus specify on your server code that the function throws SerializableException and not just Exception.

public interface ShopServices extends RemoteService
{
	/**
	 * 
	 * @gwt.typeArgs <com.example.client.ShopCategory>
	 */	
	
	public Set getShopCategories() throws SerializableException;
}

GWT automatic serialization

  • Do not forget that every class that you want to serialize must implement the IsSerializable Google interface.
  • Be careful that GWT automatic serialization, especially for collections, can be tricky. You must specify in your Java source code what your collections contain. Maybe with Java 1.5 the situation will improve.
  • Besides, if you use Hibernate, Hibernate will fill your beans (objects) with its own implementations for collections (eg it will not use the implementations from java.util, but for a set will use org.hibernate.PersistentSet). Currently (as of GWT 1.3) there are several solutions available:
    • Do a mapping between the Hibernate beans and the GWT client beans (apparently this can be somewhat automated by using Dozer).

GWT Client Widgets

  • StackPanel: If you apply a style (CSS) to this panel, it will actually be applied to the "panel in itself", NOT to the header (title) of the panel. If you wish to apply a CSS style to the header, enter the header directly as HTML code.

GWT & CSS

There is no default CSS style. The classes defined for the GWT widgets can be used in your own CSS file, but it is not mandatory to add a CSS file for a GWT page to work.

GWT & Tomcat

  • The gwt-servlet.jar file needs to be put in the WEB-INF/lib directory of your webapp. It cannot be put in the shared/lib directory of Tomcat. Some things will work but serialization across RPCs won't.
  • URLs for accessing servlets must be of the form GWT.getModuleBaseURL() + "YourServletName". I believe GWT.getModuleBaseURL() returns the name of the webapp.

GWT & Hosted Mode

If you use hosted mode, a directory named "tomcat/" is created when running GWTShell (but nothing from your source directory seems to be copied there).

  • To get the URL/servlet mapping working, you must add the <servlet> element to your GWT XML module.
  • Note that by himself, the GWTShell program will NOT compile your Java code. You must manually compile your server-side Java-code (via Ant) and specify the location of the built classes on the Java classpath when lauching GWTShell.
  • However the client side code seems to be automatically translated to JavaScript.
  • Since Google only ships a 32 bit version of GWT on Linux, you must switch to a 32 bit Java environment on Gentoo amd64 when running in Hosted Mode. Eg:
GENTOO_VM="emul-linux-x86-java-1.5" java -cp "$APPDIR/src:$APPDIR/build/WEB-INF/classes:/opt/gwt/gwt-user.jar:/opt/gwt/gwt-dev-linux.jar"
    com.google.gwt.dev.GWTShell
  • The syntax for the URLs in the Hosted Mode browser is "module_name/html_file.html".
  • You can run hosted mode in a different directory than the default one (root). Just adapt the Bash script loading Hosted Mode, like this:
APPDIR=`pwd`/`dirname $0`;
cd $APPDIR/build/hosted;
  • The best to run Hosted Mode is to dump altogether the original bash script and create your own Ant task.
  • Warning: the patterns on the public XML node of a GWT module also applies to the Hosted Mode in the integrated Tomcat container. This means that anything you specify in the excludes, for example, will not be accessible to the Tomcat container in hosted mode.

GWT Tools

Since you cannot really see the HTML source before it is created via the JavaScript, the Firefox add-on Firebug is really, really helpful with GWT.

Debugging

  • If you encounter a problem in hosted mode with a RPC, which *seems* to be working on web mode, make sure that your callback object is correct. You would encounter an error message of the type:
java.lang.NullPointerException: null
at net.elvanor.client.QueryServices_Proxy$1.onCompletionImpl(transient source for net.elvanor.client.QueryServices_Proxy:69)

Note that the remote call would still take place; however it would not complete.

GWT Problems

  • Currently GWT cannot produce pages working correctly when parsed through Firefox XHTML engine. This means that you absolutely need to avoid *.xhtml files or anything that the web server will serve as XML content to Firefox.