Using Clover with the GWT-maven plugin
For developers working with the Google Web Toolkit (GWT) software development kit and Clover for Maven 2, the clover-maven-plugin
works best with the gwt-maven-plugin.
The maven-googlewebtoolkit2-plugin has known issues that can cause the build to fail if you are building with Clover. As such, the gwt-maven-plugin is recommended.
For further background reading on the gwt-maven-plugin and interoperability with the clover-maven-plugin
, please also read this Google Groups discussion.
Instrumentation of source code
Because of the nature of Google Web Toolkit, which translates Java source code (client and shared parts) into a JavaScript, which is later being executed in a web browser, instrumentation of Java sources by Clover requires few technical tricks.
Instrumentation of server-side code only
This is a simpler case, as server-side Java sources are being complied to classes and executed directly in JVM. Therefore the only thing which has to be set up is to enable Clover and limit instrumentation to server-side code packages.
Test frameworks
The gwt-maven-plugin provides a JUnit-compatible GWTTestCase which allows to run unit tests using a web browser or htmlunit.
How to configure Maven project
Add GWT Maven Plugin to pom.xml and set desired test mode in <configuration> tag - for example htmlunit allows headless run. Example:
<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>gwt-maven-plugin</artifactId> <version>2.4.0</version> <executions> <execution> <goals> <goal>compile</goal> <goal>test</goal> <goal>i18n</goal> <goal>generateAsync</goal> </goals> </execution> </executions> <configuration> <runTarget>GwtExample.html</runTarget> <hostedWebapp>${webappDirectory}</hostedWebapp> <i18nMessagesBundle>com.atlassian.client.Messages</i18nMessagesBundle> <mode>htmlunit</mode> <htmlunit>IE7</htmlunit> </configuration> </plugin>
Add Clover Plugin definition to pom.xml and configure which sources should be instrumented with Clover - instrument only server-side code. Example:
<plugin> <groupId>com.atlassian.maven.plugins</groupId> <artifactId>clover-maven-plugin</artifactId> <version>${clover.version}</version> <configuration> <!-- Instrument only server part --> <includes> <include>com/atlassian/server/**</include> </includes> </configuration> </plugin>
Please note that includes/excludes are supported by the clover:setup goal (i.e. clover:instrument will instrument all sources).
By default, the gwt:test goal is bound to integration-test phase (and not test), so run maven with integration-test or install goal. Example:
mvn clean clover:setup install clover:aggregate clover:clover
Instrumentation of server, client and shared code
In this case we cannot use gwt:compile and gwt:test goals. The reason is that it would start translation of Java client-side and shared source code to JavaScript, searching for sources of all referenced classes, including the Clover instrumentation, which would cause a build failure.
Test frameworks
The gwt-test-utils framework provides means to simulate GWT inside JVM, it can intercept all GWT.xyz() method calls, prepare mocks using Mockito or EasyMock etc. The JUnit-compatible GwtTest allows to run unit tests without a web browser.
How to configure Maven project
Add gwt-test-utils dependency to pom.xml. Disable compile and test goals in gwt-maven-plugin. Increase memory for maven-surefire-plugin, if necessary. Example:
<dependency> <groupId>com.googlecode.gwt-test-utils</groupId> <artifactId>gwt-test-utils</artifactId> <version>0.38</version> <scope>test</scope> </dependency> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>gwt-maven-plugin</artifactId> <version>2.4.0</version> <executions> <execution> <goals> <!-- <goal>compile</goal> DISABLED --> <!-- <goal>test</goal> DISABLED --> <goal>i18n</goal> <goal>generateAsync</goal> </goals> </execution> </executions> <configuration> <runTarget>GwtExample.html</runTarget> <hostedWebapp>${webappDirectory}</hostedWebapp> <i18nMessagesBundle>com.atlassian.client.Messages</i18nMessagesBundle> <mode>htmlunit</mode> <htmlunit>IE7</htmlunit> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <configuration> <argLine>-Xmx512M -XX:MaxPermSize=128M</argLine> </configuration> </plugin>
Add Clover Plugin definition to pom.xml. Use setup goal in the initialize phase in order to make sure that source files generated by GWT will be instrumented as well. Example:
<plugin> <groupId>com.atlassian.maven.plugins</groupId> <artifactId>clover-maven-plugin</artifactId> <executions> <execution> <id>clover-initialization</id> <phase>initialize</phase> <goals> <goal>setup</goal> </goals> </execution> <execution> <id>clover-reporting</id> <phase>install</phase> <goals> <goal>aggregate</goal> <goal>clover</goal> </goals> </execution> </executions> </plugin>
Run build, for example:
mvn clean install
Example project
- Checkout GwtCloverExample sources from Bitbucket: https://bitbucket.org/atlassian/maven-clover2-plugin
- Go to src/it/gwt directory
- Use at least Java6 and Maven 2.x.
- The project demonstrates build using three profiles:
default - no Clover instrumentation
with.clover.serveronly - only server-side code is being instrumented by Clover, integration tests are performed with gwt-maven-plugin+htmlunit framework
with.clover.everything - all code is being instrumented by Clover, unit tests are performed with gwt-test-utils and mocking of server services, no integration tests - Usage (see also gwt/build.bat file):
mvn clean install
mvn -Pwith.clover.serveronly clean install
mvn -Pwith.clover.everything clean install - See output reports in <project_dir>/target/site/clover