Friday, September 2, 2011

Including external dependencies in your Maven GWT project

There are many variations on this problem but lets relate it to a concrete example.  Say perhaps you have a  series of domain objects that exist in a dependency jar, but you want to be able to serialize them and send them to the GWT client.  How do you serialize an object that doesn't already exist in your core GWT project?

There are several steps required so lets take them in a logical order.

Step 1 : Ensure your objects are serializable
Two things required here:

  • Ensure your objects are implementing serializable.
  • Ensure you have at least a no-argument private constructor.
If you don't do these things your objects cannot be serialized and sent to the client.

Step 2 : Add a GWT Module XML File
In order to indicate to the GWT Compiler that this dependency is a GWT Compilable you need to tell it so.  Therefore you will need to add the <ModuleName>.gwt.xml file in the /src/main/resources folder of the external dependency.

<?xml version="1.0" encoding="UTF-8"?>
<module rename-to="DependencyApi">
  <inherits name="com.google.gwt.user.User"/>
  <source path="domainobjects" />
</module>

In the above example "domainobjects" is the root package that you want serialized.  Similar to how a lot of GWT projects are constructed where you see a client and shared entry.

Step 3 : Export the dependency source
In order for the GWT-Compiler to compile to javascript it needs access to the source files, therefore as part of the dependencies build process you need to tell it to export the source.  An entry similar to the one below in your pom file should do it.
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.1.2</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Step 4 : Tell the GWT Compiler to add this dependency to the GWT Compile process
In the main GWT Project's pom file you need to tell it to now use this dependency and combine its source into the compilation process.  This is achieved using the GWT-Maven-Plugin's configuration section.
<configuration>
        <compileSourcesArtifacts>
          <artifact><group id>:<artifactid></artifact>
        </compileSourcesArtifacts>
</configuration>
Step 5: Include reference in the main Web Application Module.gwt.xml
Ensure you have a reference to the dependency in your main GWT Application config file.
  <!-- Dependency API -->
  <inherits name='com.acme.com.DependencyApi' />
Summary
Et Voila.  That is it complete.  A logical but not completely obvious solution to intermediate Maven users like myself.  I would love to hear from the community how they might have solved this problem.


5 comments:

  1. This comment has been removed by the author.

    ReplyDelete
  2. my previous post had my element names stripped out. here it is again:

    it appears the artifact element is no longer used within the compileSourcesArtifacts element per: http://mojo.codehaus.org/gwt-maven-plugin/compile-mojo.html

    ReplyDelete
    Replies
    1. Hmm, I think you're right. Maybe they changed it? Anyway, the example now shows use of compileSourcesArtifact sub-elements within compileSourcesArtifacts:

      http://mojo.codehaus.org/gwt-maven-plugin/user-guide/library.html

      Delete
  3. This comment has been removed by the author.

    ReplyDelete
  4. Thanks for the post! Worked for me, except for the tag "artifact" that now is "compileSourcesArtifact" as pointed out by the previous commenters.

    ReplyDelete