Social Icons

twitterfacebookgoogle pluslinkedinrss feedemail

Tuesday, January 17, 2012

Referencing third-party library source code in a GWT project.


It turns out the process is slightly involved - especially when Maven is added to the mix.  I don't know if this is the blessed way of solving this issue, but it works.

The first thing I had to do was modify the third-party library POM so that it builds the source jars. This can easily be done by adding the following plugin:

  <plugin>
    <artifactId>maven-source-plugin</artifactId>
    <groupId>org.apache.maven.plugins</groupId>
    <version>2.1.2</version>
    <executions>
      <execution>
        <id>attach-sources-jar</id>
        <phase>verify</phase>
        <goals>
          <goal>jar-no-fork</goal>
        </goals>
      </execution>
    </executions>
  </plugin>

Then, I had to run a build/install of the third-party library to install the sources in my local repo.

Next, I needed to modify the gwt-maven-plugin in my project's POM to tell it to compile the sources for my third-party library. For this, I needed the groupId and artifactId of the third-party library. I had already added this as a dependency in my project's POM and was simply able get the information from there. I then had to modify gwt-maven-plugin plugin's configuration element (in the execution element) to add the compileSourcesArtifacts element as follows:

  <compileSourcesArtifacts>
    <compileSourcesArtifact>groupId:artifactId</compileSourcesArtifact>
  <compileSourcesArtifacts>

Where the text "groupId:artifactId" are the actual groupId and artifactId of my third-party library - don't forget the colon character!

Next, I had to note the package name in the third-party library where the objects I wanted to use were located. For this example, let's assume that this package is "com.foo.bar.bat".

I added a package to my GWT project called "com.foo.bar" leaving out the final "sub-package" of "bat." In this package, I created a new gwt.xml (e.g. Foo.gwt.xml) file and used the artifactId as the name capitalizing the first letter (I don't know if this is necessary but it seems convention in GWT). I then populated this file with the following:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE module PUBLIC
  "-//Google Inc.//DTD Google Web Toolkit 1.6.4//EN"
  "http://google-web-toolkit.googlecode.com/svn/tags/2.4.0/distro-source/core/src/gwt-module.dtd">
<module>
  <source path="bat"/>
</module>

Note that the value of the "path" attribute is the final "sub-package" I left out above. Additionally, this tells GWT to try and generate JavaScript for ALL the classes in the "bat" package. If there are classes that you want to be ignored, change the <source> element to a block-level element and add a child element called <exclude> that has one attribute called "name" that contains the name of the Java file to ignore, e.g., "Bar.java".

Finally, I added a module inherit dependency to my project's gwt.xml file: <inherits name="com.foo.bar.Foo"/>.  Note that I used the capitalized name of the artifactId as the module.

2 comments:

  1. thank you. It's just what I need!

    ReplyDelete
    Replies
    1. You're welcome. It turns out, there's an even cleaner way if you happen to control the project for which you need the third-party sources.

      If you create the gwt.xml (basically defining a module) file (as above) but put it in the third-party code rather than the GWT project, as long as you add an tag in your GWT project's gwt.xml and inherit the module you created in your third-party library then you don't need the element at all.

      Delete