Tuesday, October 18, 2011

Battling Maven and GWT

 I recently decided to tackle what I came to find out was a huge problem amongst java developers who wanted to work in Google Web Toolkit, but integrated with maven to manage project structure, dependency management, and a great command line utility.  Apparently the community for mavenizing GWT applications is very broken and there has not been a very clear way to work around the problem.  

After experimenting a bit with eclipse and generating various pom archetypes, I found out the process is difficult and usually results in numerous errors in eclipse that can somehow still run through the command line.  I almost gave up, when I found some interesting info posted by google on Sep 22, 2011:

The easiest way to get a GWT POM going is to snag one from of the GWT Maven sample projects. There are currently issues with the gwt-maven-plugin archetypes, so a good starter POM is the best way to go until those issues are resolved.

For my setup, I am running Eclipse Helios on OS X Snow Leopard with the default Java SE Runtime environment (1.6.0_26 at the time).  I also have maven 3.0.3 installed on my machine.  I sampled out different plugins but I ended up with the best results using the following:

  1. Install the Google Plugin for Eclipse using the Eclipse Install New Software window.
  2. Install M2Eclipse using the Eclipse Install New Software, use the following repository:
  3. Install the M2E-Extras using the Eclipse Install New Software, use the following repository:
After all the plugins are installed, test out everything by giving Google's GWT Maven sample projects a run.  For my testing, I decided on the mobilewebapp. It can be downloaded from Google into your workspace using subversion
svn checkout http://google-web-toolkit.googlecode.com/svn/trunk/samples/mobilewebapp mobilewebapp
After thats finished, you should be able to import the project as a maven project:
  1. File -> Import -> Existing Maven Project
  2. Select the project and make sure the pom.xml in mobilewebapp is being used.
Once the project is up and done building, delete the build.xml file since we won't be using ant for this example.

You should now be able to build and run the application two different ways, try out both:
  • Select the project, then do Run -> Run As -> Web Application
  • On the command line, run the following in the project: 
    • mvn gwt:clean gwt:compile gwt:run
You can also compile the application, and package as well:
  • Right Click the project, then do Google -> GWT compile
  • On the command line, run the following to package:
    • mvn package
If you have no troubles doing all the above with the sample project, you are ready to get started with mavenizing your GWT project!  Go ahead and tag your trunk (or however you backup your work) and lets get started.


Your project will probably be set up as follows, assuming you are using the standard GWT project configuration.


  src/  
   |_ com.company.project  
   |     |_ project.gwt.xml 
   |_ com.company.project.client
   |_ com.company.project.server
   |_ com.company.project.shared
  test/  
   |_ com.company.project.common.tests
  war/  
   |_ WEB-INF/  
   |     |_ web.xml  
   |_ project.css  
   |_ project.html

First, start off by creating a few directories (to be used by maven) in the root of the project:
  • src/main/java/
  • src/main/resources/
  • src/main/webapp/
  • src/test/java/
  • src/test/resources/
From there, you are going to want to move files into the these new folders.  Either use the command line, or do this through the UI by disabling the java packages in the project by going to Build Path -> Configure Build Path -> Source and remove all of the packages.  This allows for easier viewing of the directories in the project.
  • Source code under the old src/ directory
    • Move to the new src/main/java/
  • Test code under the old test/ directory
    • Move to the new src/test/java/
  • Resource files used by the app (properties files for log4j, internationalization, etc.)
    • Move to the new src/main/resources/
  • Resource files used for tests
    • Move to the new src/test/java/
  • Everything in the old war/ directory
    • Move to the new src/main/webapp/
After all that is finished, create a empty pom.xml at the root of the project. Now the project should be structured like this:


  src/  
   |_ main/  
   |     |_ java/  
   |     |     |_ com.company.project  
   |     |     |     |_ project.gwt.xml  
   |     |     |_ com.company.project.client  
   |     |     |_ com.company.project.server  
   |     |     |_ com.company.project.shared  
   |     |_ resources/  
   |     |_ webapp/  
   |           |_ WEB-INF/  
   |           |     |_ web.xml  
   |           |_ project.css  
   |           |_ project.html  
   |_ test/        
         |_ java/  
         |     |_ com.company.project.common.tests  
         |_ resources/
  pom.xml

Make sure that all of the previous contents of the project are now moved to their new locations. I only listed the basics for simplicity.  You will end up deleting those old and empty directories soon.

So for the empty pom.xml, as google said go ahead and copy and paste the pom from their sample project and paste it into the empty pom.  Make a few changes:
  • Project info like groupid, artifactid, name, etc.
  • Configuration of the gwt-maven-plugin to point to your EntryPoint Module
If you have any extra dependencies in the build path needed for the app, make note of them and wait until after the next few steps to add them to the pom. Go ahead and do the following now:
  1. Remove the project from eclipse, but do not delete from the disk
  2. File -> Import -> Existing Maven Project
  3. Browse to the project and make sure our new pom is selected
Maven will set up everything for us, down to the version of java (which we defined as 1.6).  We can delete all of the old directories at this time (war/ and test/).  Modify the pom to add or remove dependencies as need be.  Other google sample projects contain the repositories, plugins, and dependencies for adding things like Spring Roo, Spring Security, and JPA2.  Correct whatever errors remain in the project and go ahead and try to run it as a web application and run maven on the command line.  As you can see, the project is now launching from target instead of war.


Here is the site I got my info from:
http://code.google.com/p/google-web-toolkit/wiki/WorkingWithMaven


ISSUES and FAQ


I have had some issues with the java compiler facet settings, here is the error I get:


"Java compiler level does not match the version of the installed Java project facet"


I found the easiest way to fix this is to edit the java facet version in a settings file used by maven. It is located in the following directory in the root of the project:



/.settings/org.eclipse.wst.common.project.facet.core.xml

1 comment:

  1. Go ahead and leave any comments or clarifications. If you run into a problem, lets try to resolve it and add it to the FAQ part of the post. Thanks!

    ReplyDelete