Christian Posta bio photo

Christian Posta

Chief Architect, cloud application development @ Red Hat, author Microservices for Java Developers, open-source enthusiast, committer @ Apache, Cloud, Integration, Kubernetes, Docker, OpenShift, Fabric8, #blogger

Twitter Google+ LinkedIn Github Stackoverflow

Apache Maven is a popular project-management tool that allows you to model your projects in XML and then streamline the development lifecycle by taking advantage of dependency management and convention over configuration. I use Maven for all of my new projects, and I have had the chance to use Maven to manage my GWT projects. The purpose of
this blog entry is to demonstrate to the GXT community how to get Maven up and running to manage one of their projects.

First, I'd like to point out that the folks over at Sonatype have put together a terrific book detailing the use of Maven. I definitely recommend browsing through the first few chapters to get a better understanding of what Maven is, how to use it, and examples of Maven projects. Sonatype also put together the m2eclipse plugin for integrating and managing your Maven projects in Eclipse. Point your Eclipse update manager to http://m2eclipse.sonatype.org/update/

Second, I'd like to thank the Charlie Collins and the creators of the gwt-maven plugin. They did a good job of putting together an easy-to-use plugin for GWT projects. I use the gwt-maven plugin in the example that follows.

I'd like to also mention that the purpose of this blog entry is not to convince anyone to use Maven. I'll leave that to the Maven documentation. This blog entry is simply an introduction to using Maven with GXT/GWT. There are plenty of other build mechanisms out there that could arguably be used in a comparable fashion. For example, the developers of GXT use Apache ANT for their build environment. Combining ANT with Apache IVY provides a suitable alternative to some of the features discussed in this blog.

Getting Started

To get started, download the code for this project. It is simply the Ext-GWT mail reference application with a Maven POM and directory structure used to build the project with Maven. I recommend you browse through the code briefly to get an cursory understanding of the directory structures. We will start by examining the POM for the project, so you may want to get familiar with that too.

Building the project

You'll need to have Apache Maven installed properly before you can build the project. Go to http://maven.apache.org/ to download Maven.

After downloading the source code and extracting it to a suitable directory, you can kick off the build lifecycle by typing the following Maven command from the directory that contains the pom.xml file:

mvn install

Maven will do its thing to compile, run tests, and package the project; the build should end succesfully. Maven requires access to the internet to download dependencies, so verify you're connected.

After a succesfull install, look in the "target" directory to find the "mail.war" file.

To run the project in GWT hosted mode, type the following command at the prompt:

mvn gwt:gwt

NOTE: unfortunately, running the hosted mode with the "gwt" prefix no longer works. A competing gwt maven plugin fromcodehaus has caused a clash with the "gwt" prefix. See the last section of this post for more.

The pom.xml

At the root of the project is the Maven POM file. This file is the Project Object Model that is used to model the project including the Maven plugins and project dependencies. For more info on a Maven POM, see the reference documentation. We'll step through the pom.xml file that comes with this project to explain each of its materially important xml entries.


	4.0.0

	com.extjs.samples
	gxt-mail
	war
	1.1.3

	GXT Mail compiled with Maven

This section contains the basic Maven POM coordinates to identify the project. Nothing too special about this part, but it's necessary.

	
		1.5.2
		com.extjs.gxt.samples.mail.Mail
		index.html
	

This section contains project-specific properties, including the version of GWT to use, the name of the GWT module to compile, and the name of the host html page for the GWT module. If you'd like to use this POM to compile your own GWT project, you can replace these project properties to fit your own specs.

	
		
			gwt-maven-plugins
			
                http://gwt-maven.googlecode.com/svn/trunk/mavenrepo/
            
		
	

At the moment, gwt-maven has its plugins hosted at their repository at Google Code. This section contains the plugin repository for gwt-maven.

	
		
			com.extjs
			gxt
			1.1
		
		
			com.google.gwt
			gwt-servlet
			${gwtVersion}
			runtime
		
		
		...
		
		
			junit
			junit
			4.1
			test
						
	

This section models the project's dependencies. You'll see that the Ext-GWT library, the GWT jars, and other ancillary dependencies are listed here. NOTE: The GXT jar on the Maven Central Repository is outdated. See the section below on how to manually install the jar to your local repository.

	
		mail
		

		...
		
		
		
	

This section is probably the most important as far as configuring Maven to compile GWT sources (actually, the stuff I left out of this section is the most important). We look at the plugin configuration below, but I wanted to point out that the "finalName" element contains the name of the war file that will be produced. If you do not define a "finalName," the project name and its POM coordinates will be used to derive the war filename.

Each of the following four sections will be the plugins described in the "plugins" section.

			
				com.totsp.gwt
				maven-googlewebtoolkit2-plugin
				2.0-beta25
				
					INFO
					
						${gwtModule}
					
					${gwtModule}/${gwtHostPage}
					
					false
					-Xmx512m
					${gwtVersion}
				
				
					
						
							mergewebxml
							compile
							test
						
					
				
			

This is the gwt-maven plugin declaration and its associated configuration. Lines 5-15 specify the configuration parameters including the GWT compile target (which is our GWT module name), the run-time target (including the host page), and finally the version of GWT to use.

The "executions" element enumerates the plugin goals to run:

  • mergewebxml - this goal takes the web.xml file in the src/main/webapp/WEB-INF/ directory and merges it with the GWT module xml (*.gwt.xml) file. It will automatically generate a servlet mapping in the web.xml file for each servlet defined in the GWT module xml file.
  • compile - this goal invokes the GWT compiler on the source code
  • test - this goal invokes the testing framework (JUnit) on the project tests if they exist (there are no tests defined for this project)

The gwt-maven plugin contains other goals. See the documentation for more details.

			
				org.apache.maven.plugins
				maven-dependency-plugin
				
					
						unpack
						compile
						
							unpack
						
						
							
								
									com.google.gwt
									gwt-dev
									${gwtVersion}
									${platform}-libs
									zip
									false
								
							
						
					
				
			

Since the GWT libraries are specific for each platform (windows, linux, mac, etc), Maven will need to decide which platform we are using (using the "profiles" entries below) and then use the maven-dependency-plugin to unpack the correct jar for the gwt native libraries. This is the "automatic" mode for unpacking the platform jars. See the documentation for more details.

			
				org.apache.maven.plugins
				maven-war-plugin
				
					target/web.xml
					.gwt-tmp/**
				
			

Since we use a "merged" web.xml file, we'll need to tell the maven-war-plugin which web.xml to use. Othewise, it will just use the one in src/main/webapp/WEB-INF. We can also choose to exclude some of the gwt temp files.

Another note about the web.xml file and the mergewebxml goal. The web.xml file in the src/main/webapp/WEB-INF directory DOES NOT contain any of the servlet mappings for the GWT RPC servlets; the mappings will be generated automatically by mergewebxml. The reason for this is the plugin also uses the web.xml file in the src/main/webapp/WEB-INF directory for the hosted-mode tomcat. The plugin automatically addes the "GWTShellServlet" servlet to properly serialize objects in hosted mode. If you also have your own GWT-RPC servlets mapped, it doesn't work properly in hosted mode. This is something I've inquired about at the gwt-maven project web page.

			
				org.apache.maven.plugins
				maven-compiler-plugin
				
					1.5
					1.5
				
			

For the last plugin, we tell the javac compiler to use a source and target of Java 1.5

	
		
			gwt-dev-windows
			
				windows

			
			
				true
				
					windows
				
			
		
		
		...
		
		
			gwt-dev-linux
			
				linux
			
			
				false
				
					linux
				
			
		
	

Finally, we use Maven activation profiles to let the project know which platform on which we're developing. The activation takes place if the "activation" element's entries are true (for example, if the platform is of the "windows" family, the property "platform" will be usable with the value of "windows").

Deploy

After running the "mvn install" command, browse to the "target" directory to find the mail.war file. Deploy this file to your application server and browse to (for example) "http://hostname:port/mail/com.extjs.gxt.samples.Mail/".

Installing GXT jars locally

At this point, the GXT jars are not updated on the Maven Central Repository. You may want to install the jar into your local repository so that you can reference it from the POM. Follow these steps to install into your local repository:

  1. Download the GXT library
  2. Unpack the GXT library to a suitable directory
  3. From the directory that contains the "gxt.jar" file, type the following command:
    mvn install:install-file -Dfile=gxt.jar -DgroupId=com.extjs -DartifactId=gxt -Dversion=${version.number}
    

    where ${version.number} is the GXT library version number.

After installing the GXT library locally, you can change the dependency entry in the POM:

	
		
			com.extjs
			gxt
			${version.number}
		
		
		...

gwt-maven-plugin at mojo.codehaus.org

A new project has evolved over at the mojo.codehaus.org website that will provide a GWT plugin. The owners of the code at the Google Code's gwt-maven project (the plugin used above) have decided to work with Nicolas De Loof at codehaus to merge the two projects.

At the time the codehaus gwt maven plugin was uploaded to the Maven central repository, the goal used in the Google Code' gwt-maven plugin to run the hosted-mode GWT shell no longer worked. Use the following goal (with the complete plugin name) to run hosted mode with the gwt-maven plugin:

mvn com.totsp.gwt:maven-googlewebtoolkit2-plugin:gwt

I encourage any of you interested to pay close attention to the Maven project at codehaus. Although it is not as mature as the Maven project at Google Code, it does perform some common GWT tasks (compile, eclipse configs, etc) and from what I can tell from my initial investigation, it may end up being much easier to use.