Sunday 17 January 2010

Google Appengine and Maven - another hack for datanucleus plugin

After researching for mavenizing an Appengine pet project, most of the links that Google search returned were really old when first version of AppEngine was released and did not match the expectations. Also unfortunately there is really no maven plugin that supports the latest version as Google publishes them or a plugin that allows you to point to a local installation, so that you could update at the speed of Google releasing updates for AppEngine (as of this writing, there were atleast 3 updates in the shorter period of 2 weeks)

Thanks to Salient Point, this was the best article to configure a maven project and it allowed to configure any AppEngine version with the simplicity of changing a couple of variables in a script file and building the maven project. However the only caveat that needed a few hours of debugging was the maven-datanucleus-plugin, as again the versions of the Jar files provided by datanucleus repository and the ones that are published by Google were slightly different and it was more simpler to use the same philosophy of having all the Jars provided by Google rather than downloading them from a different repository.

On this note, the following are the only deviation of configurations from the original post 1) Define the local directory to which the AppEngine Jars have been downloaded, the preferred way is to use profiles such that we could specify a default location in each platform (windows / mac)

        <profile>
            <id>gwt-dev-windows</id>
            <properties>
                <platform>windows</platform>
                <appengine.sdk.root>C:\Java\appengine-java-sdk-${appengineVersion}</appengine.sdk.root>
            </properties>
            <activation>
                <activeByDefault>false</activeByDefault>
                <os>
                    <family>windows</family>
                </os>
            </activation>
        </profile>
2) Specify a antrun task that performs the datanucleus enhancement for entity objects rather than the datanucleus plugin
            <plugin>
                <artifactId>maven-antrun-plugin</artifactId>
                <executions>
                    <execution>
                        <id>datanucleus-enhance</id>
                        <phase>process-classes</phase>
                        <configuration>
                            <tasks>
                                <property name="appengine.tools.classpath"
                                    location="${appengine.sdk.root}/lib/appengine-tools-api.jar"/>
                                <property name="dependency_classpath" refid="maven.dependency.classpath"/>

                                <taskdef name="enhance" classname="com.google.appengine.tools.enhancer.EnhancerTask"
                                    classpath="${appengine.tools.classpath}"/>
                                <enhance failonerror="true" api="JPA">
                                    <classpath>
                                        <pathelement path="${appengine.tools.classpath}"/>
                                        <pathelement path="${dependency_classpath}"/>
                                        <pathelement path="target/classes"/>
                                    </classpath>
                                    <fileset dir="target/classes" includes="**/*.class"/>
                                </enhance>
                            </tasks>
                        </configuration>
                        <goals>
                            <goal>run</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
Alas it works like magic for us and we are able to upgrade the AppEngine versions as and when they are released by Google.

Also to note is the link on configuring a multi-project setup that is documented on the maven-gwt-plugin documentation that helps to organize your code into multiple projects (separating the core API / UI / service implementation and AppEngine deployment). Refer to our sample project setup that is hosted at http://code.google.com/p/scrumsp