Another aspect of GWT-Maven to be familiar with is that can help you configure the embedded Tomcat container GWT uses in the Hosted Mode shell - Tomcat Lite.
This is stripped down version of Tomcat that works a bit differently than what most developers are used to. It's also an older version of Tomcat, 5.0.28, and some of the configuration is different than 6.x or 5.5.x.
See the simpledatasample sample application for a reference of many of the features discussed here.
The first thing to be aware of is that GWT generates a "tomcat" directory (CATALINA_BASE) and then builds out related structure there for use with the embedded server.
With GWT-Maven the default CATALINA_BASE that is generated is $project.build.dir/tomcat, (you can set the tomcat parameter to the plugin configuration to change this location if desired).
The structure of the generated Tomcat directory, regardless of where you place it, is as follows:
/conf
web.xml
/gwt
/localhost
ROOT.xml
/webapps
/ROOT
/WEB-INF
web.xml
/work
You will notice 3 .xml files in that structure.
The first, conf/web.xml is a superset web.xml that has some mime types and such in it, you don't need to worry about that one 99% of the time.
The second, conf/gwt/localhost/ROOT.xml is the GWT shell "context.xml" file. You can configure a Tomcat specific context.xml for the shell, manually, or automatically with GWT-Maven (see the context.xml section below).
The third, webapps/ROOT/WEB-INF/web.xml is the GWT shell "web.xml" deployment descriptor file. This is the one you want to configure for the shell, either manually, or automatically with GWT-Maven (see the web.xml section below).
GWT-Maven can use a source web.xml file, the default location of which is src/main/webapp/WEB-INF/web.xml, with the embedded Tomcat for the GWT shell. If this file is present in your SOURCE tree, it is used to configure the shell. (Also note that you can change the default location by setting the webXml parameter to GWT-Maven, if needed.)
It does not matter whether or not you use the GWT-Maven "mergewebxml" goal or not (more on that in a moment), if you have a source web.xml file, it will be picked up and used for the embedded webapps/ROOT/WEB-INF/web.xml by the "gwt" goal. GWT-Maven will make one addition to that file before it is used - it will add the GWTShellServlet to it:
<!--inserted by gwt-maven-->
<servlet>
<servlet-name>shell</servlet-name>
<servlet-class>com.google.gwt.dev.shell.GWTShellServlet</servlet-class>
</servlet>
<!--inserted by gwt-maven-->
<servlet-mapping>
<servlet-name>shell</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
This addition lets the shell function normally by proxying RPC requests to the correct classes (without needing specific entries for each while in the shell). The advantage here with GWT-Maven is that the REST of your source web.xml will also be there, you can have other servlets, servlet filters, and anything else. (Everthing you configure has to also be available on the classpath for the shell, of course. For example connection pools, Spring, etc - but that's easy with GWT-Maven - just add those things as dependencies to your POM and GWT-Maven will make sure they are on the classpath for the shell).
Note that the default GWTSHellServlet mapping URL (or "url-pattern") is "/*", which is fine for most cases. Nevertheless, if you do wish to change this for special circumstances you can by using the "shellServletMappingURL" configuration parameter.
When you HAVE a source web.xml file, whether or not you use mergewebxml, it is used for the GWT shell.
This is where the GWT-Maven mergewebxml goal comes in handy. This goal goal can inspect your module chain (the GWT module you are currently using, and anything in the inherits hierarchy) and "merge" any GWT-RPC servlet entries from your modules, with your DEPLOY time web.xml file.
This merging is a combination of your SOURCE web.xml file (which is never modified by GWT-Maven), your GWT module descriptor (also never modified by GWT-Maven), and an output DEPLOY ready build web.xml file.
This goal allows you to NOT have to define all your GWT RPC servlets in your source web.xml file, but you can still have a source web.xml file for other stuff (see the previous section). Then at build time, the merge step makes individual servlet web.xml entries for every GWT-RPC servlet it encounters (from your GWT module).
To enable this you need to have the mergewebxml goal present in the executions section of the plugin configuration.
You can also not use this, if you do not prefer, by simply NOT including the mergewebxml goal.
Note that the default mapping URL (or "url-pattern") for a merged servlet entry is "/modulename/servletpath", where the module name is prepended to the servlet path from your GWT module - this is fine for most cases. Nevertheless, if you do wish to change this you can set the "webXmlPathAsIs" configuration parameter to true, and then the exact path in your GWT module will be used (nothing will be prepended).
If you do you use mergewebxml the output file will be $project.build.dir/web.xml (usually that means "target/web.xml").
The last thing you need to do in order to USE this file with your WAR, is to configure the war plugin to use it. This can be done as follows:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<webXml>target/web.xml</webXml>
</configuration>
</plugin>
There are a few things to know when dealing with the Tomcat specific context.xml file in regards to GWT and GWT-Maven.
First, GWT uses Tomcat 5.0.28, so you will need to have a context.xml configuration for THAT version - and there have been many changes in Tomcat 5.5.x and 6.x. Because of this, and because you will probably want to actually deploy to a newer version of Tomcat (if you use Tomcat), you may need to have MULTIPLE context.xml files: one for use with the GWT shell, and one for production deployment Tomcat.
Second, you have to use the GWT-Maven contextXml parameter to configure GWT-Maven to use your source context.xml file with the embedded Tomcat server. There is no default for this parameter (because there is no regular place for a Tomcat specific file like context.xml). If you set your contextXml parameter though, to a reasonable source location like src/main/webapp/META-INF/contextGwt.xml, then it will be used to replace the shell ROOT.xml file. (Again, you probably want a different src/main/webapp/META-INF/context.xml for regular Tomcat use).
Sometimes you have a special file you need to bring along into the embedded Tomcat at a special location (rather than just on the classpath). It depends on how you are using a component, and how that component looks for its resources, but you may need a file like WEB-INF/applicationContext.xml or WEB-INF/persistence.xml for the shell (Spring usually looks at the classpath too, rather than just a relative file location, but this is just a general example).
If that is the case you can generally use the Ant Run plugin to manipulate the embedded Tomcat structure as needed, for example:
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>applicationContextCopy</id>
<phase>compile</phase>
<configuration>
<tasks>
<copy
file="${basedir}/src/main/webapp/WEB-INF/applicationContext.xml"
toFile="${basedir}/target/tomcat/webapps/ROOT/WEB-INF/applicationContext.xml" />
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
Many people prefer not to try to configure the embedded GWT Tomcat instance, and instead prefer to use the GWT -noserver option. Keep in mind that with GWT-Maven this is still possible. Just use the noserver parameter in your plugin configuration, and GWT-Maven will pass -noserver to the shell, and not configure anything related to the embedded Tomcat.
(Keep in mind that though noserver is a necessity in some situations, it also has some drawbacks of it's own. Refreshing the shell when you are using noserver will not update the server side, of course. Also, GWTTestCase based tests will not work at all with a nosever setup - the JUnitShell does not have a noserver option.)