Steps
Add clover-maven-plugin to <build> section
- set the includesAllSourceRoots property to true (default is false) if you're interested in code coverage for JAXB generated sources
- bind the clover:setup goal to process-sources phase (so that it's executed after sources generation)
- bind the clover:clover goal to verify or install phase (so that report is generated after test execution)
<plugin> <groupId>com.atlassian.maven.plugins</groupId> <artifactId>clover-maven-plugin</artifactId> <version>${clover.version}</version> <configuration> <!-- Instrument all source files, also generated by JAXB. Set to false if you're not interested in such details (default is false) --> <includesAllSourceRoots>true</includesAllSourceRoots> </configuration> <executions> <execution> <!-- Call the clover:setup after JAXB sources are generated but before compilation --> <id>main1</id> <phase>process-sources</phase> <goals> <goal>setup</goal> </goals> </execution> <execution> <!-- Call the clover:clover and generate report after tests are run --> <id>main2</id> <phase>verify</phase> <goals> <goal>clover</goal> </goals> </execution> </executions> </plugin>
Add jaxb-api plugin to <dependencies> section
- this is required to run unit tests
<dependencies> <dependency> <groupId>javax.xml.bind</groupId> <artifactId>jaxb-api</artifactId> <version>${jaxb.version}</version> </dependency> </dependencies>
Add maven-jaxb2-plugin to <build> section
- you might need to add jaxb-xjc and jaxb-impl as plugin's dependencies (see Troubleshooting chapter)
- you can use extensions like property-listener-injector
<plugin> <groupId>org.jvnet.jaxb2.maven2</groupId> <artifactId>maven-jaxb2-plugin</artifactId> <version>0.8.1</version> <executions> <execution> <goals> <goal>generate</goal> </goals> <configuration> <extension>true</extension> <schemaLanguage>DTD</schemaLanguage> <schemaIncludes> <schemaInclude>*.dtd</schemaInclude> </schemaIncludes> <bindingIncludes> <bindingInclude>*.jaxb</bindingInclude> </bindingIncludes> <args> <arg>-Xinject-listener-code</arg> </args> </configuration> </execution> </executions> <dependencies> <dependency> <groupId>com.sun.xml.bind</groupId> <artifactId>jaxb-xjc</artifactId> <version>${jaxb.version}</version> </dependency> <dependency> <groupId>com.sun.xml.bind</groupId> <artifactId>jaxb-impl</artifactId> <version>${jaxb.version}</version> </dependency> <dependency> <groupId>org.jvnet.jaxb2-commons</groupId> <artifactId>property-listener-injector</artifactId> <version>1.0</version> </dependency> </dependencies> </plugin>
Sample project
- Checkout code from Bitbucket: https://bitbucket.org/atlassian/maven-clover2-plugin
- Go to src/it/jaxb
- Run mvn clean install
- Generated report will be available in target/site/clover directory
Troubleshooting
Problem: Class not found - javax.activation.DataHandler with an error message like below:
[INFO] [jaxb2:generate {execution: default}] [FATAL ERROR] org.jvnet.mjiip.v_2.XJC2Mojo#execute() caused a linkage error (java.lang.NoClassDefFoundError) and may be out-of-date. Check the realms: [...] [ERROR] FATAL ERROR [INFO] ------------------------------------------------------------------------ [INFO] javax/activation/DataHandler [INFO] ------------------------------------------------------------------------ [INFO] Trace java.lang.NoClassDefFoundError: javax/activation/DataHandler at com.sun.tools.xjc.model.CBuiltinLeafInfo.<clinit>(CBuiltinLeafInfo.java:303) at com.sun.tools.xjc.reader.dtd.TDTDReader.<clinit>(TDTDReader.java:442) [...]
Solution: Define com.sun.xml.bind::jaxb-xjc and com.sun.xml.bind::jaxb-impl as <dependencies> for maven-jaxb2-plugin as in example chapter above.
Problem: When using the Clover Plugin together with the the JAXB2 Plugin, the build fails during instrumentation due to an unresolved clover.jar with an error message like below:
[ERROR] BUILD ERROR [INFO] ------------------------------------------------------------------------ [INFO] Error configuring: org.jvnet.jaxb2.maven2:maven-jaxb2-plugin. Reason: Error evaluating plugin parameter expression: project.compileClasspathElements [INFO] ------------------------------------------------------------------------ [INFO] Trace org.apache.maven.lifecycle.LifecycleExecutionException: Error configuring: org.jvnet.jaxb2.maven2:maven-jaxb2-plugin. Reason: Error evaluating plugin parameter expression: project.compileClasspathElements at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor.java:707) [...] Caused by: org.apache.maven.artifact.DependencyResolutionRequiredException: Attempted to access the artifact >>>>>com.atlassian.clover:clover:jar:X.Y.Z:compile<<<<<; which has not yet been resolved at org.apache.maven.project.MavenProject.addArtifactPath(MavenProject.java:1906) [...]
Solution: Define a dependency to com.atlassian.clover::clover in your POM, for example:
<dependency> <groupId>com.atlassian.clover</groupId> <!-- note: com.cenqua.clover for 3.x versions --> <artifactId>clover</artifactId> <version>4.1.1</version> </dependency>