Setting up GWT2 project with gwt-maven-plugin

GWT2 offers a lot of exciting new features: OOPHM, SOYC, code splitting, declarative UI, to name a few. This evening, I experimented setting up a GWT2 project using Codehaus’s gwt-maven-plugin.

I’m using Eclipse, so obviously, you need m2eclipse and Google Eclipse Plugin. First step is creating a Maven project:
File->New->Project…->Maven Project

In the archetype selection dialog, select org.codehaus.mojo.gwt-maven-plugin:1.1.

We choose this to create an archetype but 1.1 doesn’t work with GWT2. Later on, we will modify pom.xml to use another version of the plugin.

Enter your project’s GroupId, ArtifactId, Version, and Package -> Finish

The plugin generates an archetype of GWT 1.6 project. In Eclipse, open pom.xml. As stated earlier, gwt-maven-plugin 1.1 doesn’t work with GWT2. You need 1.2, but since 1.2 hasn’t been released, we will use the snapshot version. The snapshot version is hosted on codehaus’s snapshot repository, so we need to add the repository first.

Id: codehaus-snapshot-repository
Name: (anything you like)
URL: http://snapshots.repository.codehaus.org

Then, change the version of gwt-maven-plugin from 1.1 to 1.2-SNAPSHOT

Also, you need to specify the module and runTarget in the configuration of the plugin, something similar to the following:

		<plugins>
			<plugin>
				<groupId>org.codehaus.mojo</groupId>
				<artifactId>gwt-maven-plugin</artifactId>
				<version>1.2-SNAPSHOT</version>
				<executions>
					<execution>
						<goals>
							<goal>compile</goal>
						</goals>
					</execution>
				</executions>
				<configuration>
					<module>com.mycomp.demo.mygwt2.Application</module>
					<runTarget>com.mycomp.demo.mygwt2.Application/Application.html</runTarget>
				</configuration>
			</plugin>
  </plugins>

Save the pom. Eclipse will be busy fetching the dependencies and building the project.

After it’s done, it’s time to create launchers.

Right click on pom.xml, Run As->Maven Build…, in the Run Configurations dialog, put “gwt:compile gwt:run” as the goals.

Hit “run”, GWT Development Mode application will appear.

The final missing piece is the debug mode. One of the advantages of using GWT is developing AJAX application with existing Java tooling. So let’s go ahead and set it up.
Right click on pom.xml->Run As->Maven build…
In the following dialog, enter “gwt:debug” as goals, save it.

Click on the dropdown of the debug button on the toolbar, select “Debug Configurations”.
In the left panel, find “Remote Java Application”, select it and click the icon for “New launch configuration” (top left corner). Accept defaults, save, and close.

Put a breakpoint at Application.onModuleLoad(), start the debug server by running the debug launcher we just created. (the one with goal gwt:debug). When you see “Listening for transport dt_socket at address: 8000” in the console output, run the attach launcher we just created (the remote debugger). The GWT Development Mode app pops up. Because GWT2 uses OOPHM (Out Of Process Hosted Mode), you need to copy the start URL and paste it in a browser (I’m using FF). If it’s the first time you run hosted mode like that, you will be asked to install a Firefox plugin. After it’s installed, paste the URL into the address bar. If everything goes well, your breakpoint will be hit.

There you have it. A sample mavenized GWT2 project. Enjoy the goodies offered by both GWT2 and Maven!

Setting up a Clojure Project with Maven

In this blog post I’m going to record my recent experience in setting up a Clojure project using the clojure-maven-plugin.

Clojure-Maven-Plugin

First you need to compile the plugin from source:
git clone git://github.com/talios/clojure-maven-plugin.git
cd clojure-maven-plugin
mvn install
Of course, you will need to have Maven2 installed already.

After that, the compiled plugin jar will be in your maven local repository. Create a pom.xml file to use the plugin. I’m using the pom.xml from my project Programming Collective Intelligence as an example:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>pci</groupId>
    <artifactId>pci</artifactId>
    <name>Programming Collective Intelligence</name>
    <version>0.0.1-SNAPSHOT</version>

    <build>
        <plugins>
            <plugin>
                <groupId>com.theoryinpractise</groupId>
                <artifactId>clojure-maven-plugin</artifactId>
                <version>1.2-SNAPSHOT</version>
            </plugin>
        </plugins>
    </build>

</project>

Also, setting up clojure-lang and clojure-contrib (optional, but nice to have) as dependencies as follows:

    <dependencies>
        <dependency>
            <groupId>org.clojure</groupId>
            <artifactId>clojure-lang</artifactId>
            <version>1.1.0-alpha-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.clojure</groupId>
            <artifactId>clojure-contrib</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

Clojure builds haven’t reached Maven central repository yet, so you need to build Clojure from source, and install it into your local repository by using
mvn install:install-file -Dfile=clojure-lang.jar -DgroupId=org.clojure -DartifactId=clojure-lang -Dversion=1.1.0-alpha-SNAPSHOT -Dpackaging=jar

Do the same for clojure-contrib.

You can also create a directory in under your project root and have pom.xml looking for artifacts in that directory as well. I found this to be useful for artifacts that are not in the central repository. To do so, add repository definition in pom.xml:

    <repositories>
        <repository>
            <id>lib-repo</id>
            <name>lib-m2-repository</name>
            <url>file://${basedir}/lib-repo</url>
            <layout>legacy</layout>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
            <releases>
                <checksumPolicy>ignore</checksumPolicy>
            </releases>
        </repository>
    </repositories>

Afterwards, you need to setup your directory structure as follows:

${project_root}
-- lib-repo
    -- org.clojure
        -- jars
            * clojure-lang-1.1.0-alpha-SNAPSHOT.jar
            * clojure-contrib-1.1.0-alpha-SNAPSHOT.jar
        -- poms
            * clojure-lang-1.1.0-alpha-SNAPSHOT.pom
            * clojure-contrib-1.1.0-alpha-SNAPSHOT.pom

The pom files can be found in your local repository after you’ve done mvn install:install-file.

If you want to run clojure:repl goal, you’d better add jline to your dependency as well:

<dependencies>
  ...
        <dependency>
            <groupId>jline</groupId>
            <artifactId>jline</artifactId>
            <version>0.9.94</version>
        </dependency>

  ...
</dependencies>

By convention, the plugin compiles everything under ${project_root}/src/main/clojure and ${project_root}/src/test/clojure.

It’s hard to imagine working in a language like Clojure without automated unit tests. Fortunately, clojure-maven-plugin has the clojure:test goal which runs unit tests. All you need to do is telling the plugin where’s the entry point of your unit test. Add the following configuration in the build section:

    <build>
        <plugins>
            <plugin>
                <groupId>com.theoryinpractise</groupId>
                <artifactId>clojure-maven-plugin</artifactId>
                <version>1.2-SNAPSHOT</version>
                <configuration>
                    <testScript>src/test/clojure/pci/test.clj</testScript>
                </configuration>
            </plugin>
        </plugins>
    </build>

The test script looks like the following:

(ns my-namespace
  (:use clojure.contrib.test-is
          test-module-1
          test-module-2))
(run-tests 'test-module-n)

There you have it! The sample files can be found in my pci-clj project on GitHub.