Today, we turn to some “fun” making Maven, Google App Engine, and Eclipse work together nicely. I like Eclipse I lot. I know its not everyone’s favorite, but it is my choice of IDE. Similarly, I know Maven isn’t everyones… ok, its no one’s favorite, but it does solve a number of problems quite well and I peacefully co-exist with it right now. Maven and Eclipse are enough to make people complain loudly to me at work, but today I wanted to build a GAE project, in Eclipse, and using Maven to manage my dependencies (I’m going to have a number on this little project of mine and its good for what I need).
Google certainly has a nice Eclipse plugin for managing GWT and GAE projects, but it doesn’t conform to Maven conventions. After trying several times to coerce a GAE project into a Maven structure I gave up and did some searching. I found https://developers.google.com/appengine/docs/java/tools/maven to be generally useful but it required some modifications for the current versions of things. Here is what I had to do to get everything working together:
- Eclipse Java EE IDE for Web Developers, Version: Kepler Release, Build id: 20130614-0229
- Maven 3.1.0 installed outside of Eclipse (in my devtools folder if it matters)
- JDK 1.7.0_25
- Windows 7
A basic REST servlet using:
- GAE 1.8.3
- Jersey 2.2
- Final WAR deployed into my GAE account
Step 1: Add the External Maven to Eclipse
I didn’t realize it was going to be important to have an external Maven installation but it turns out that it is (reasons later). In the Eclipse Preferences, search for Maven, and look for the Installations tree node. Add a new installation by browsing for your devtools equivalent location. Once added, make sure the checkbox is on the External one. You may also need to update where your settings.xml is pointing both here in the Installations, and/or in the User Settings. I have both pointing at the settings.xml in the external maven configuration folder.
Step 2: Update Eclipse Maven with Remote Archetype catalog
In that same Maven area above, look for the Archetypes tree node. Add a remote catalog providing http://repo1.maven.org/maven2/archetype-catalog.xml in the catalog file box (name it if you want, I didn’t).
Step 3: Create the project stub
Using the Eclipse project wizard create a new Maven Project. The second step in the wizard selects an archetype, look for com.google.appengine.archetypes:skeleton-archetype. Select your group and artifact ids (I choose “mavengaetestproject” for both) and it will create a nice stub GAE project. Note that the artifact id becomes the Eclipse project name. That annoys me because my Eclipse project names don’t always match my maven artifact names, but considering what we’re trying to accomplish, I’ll let this one slide. If I’ve missed where I can name the project, please let me know.
Step 4: Fix up the default pom.xml
The default pom is set up for GAE version 1.7.5 so change the appengine.target.version property to 1.8.3 to pull in the latest GAE environment.
Step 5: Test out the basic war
One of the nice things about the skeleton-archetype is that it comes with appengine-maven-plugin already set up. That gives us some maven goals that help make up for the lack of the GAE Eclipse plugin.
Right clicking on the project node, Run As, Maven Build…, set the goal to be appengine:devserver and then run it.
As of the time of this writing there’s a problem:
[ERROR] Failed to execute goal com.google.appengine:appengine-maven-plugin:1.8.3:devserver (default-cli) on project mavengaetestproject: The plugin com.google.appengine:appengine-maven-plugin:1.8.3 requires Maven version 3.1.0 -> [Help 1]
Eclipse Kepler is running Maven 3.0.4 internally, and in one of those warning messages I never read on the Maven Installations configuration dialog it says “Note: Embedded runtime always used for dependency resolution…”. Basically, by default, any Run As, Maven command is using Eclipse’s embedded Maven configuration.
This can be fixed by going into the Run As, Run Configurations… dialog and searching for DevAppServer, click on it. At the bottom there is a Maven Runtime combobox, select the external Maven entry. Apply and then run. This time it should work better.
Open a browser to http://localhost:8080/_ah/admin to prove that its working.
One annoying side effect: killing the process inside the Eclipse console doesn’t seem to kill the real process so I have to manually kill it when I’m done testing. Any suggestions on this would be welcome.
At this point we have a working GAE project that does nothing. But, it is Maven-ized and working in Eclipse. In the next post, I’ll pull Jersey in and make sure Maven and Jersey and everything are all working correctly.