Friday 16 August 2013

PMD: Part technical note, part confession

I've been meaning to do some code style / complexity checks for a while. JavaNCSS seems to be broken with Java 1.7 syntax so I'm just using PMD. First, a quick how-to for the Jenkins install to help recreate the effect. First, create a slave instance which will stop rather than terminate, using the slave AMI. Then...




sudo yum update
wget http://downloads.sourceforge.net/project/pmd/pmd/5.0.5/pmd-bin-5.0.5.zip
cd /usr/local
sudo unzip ~/pmd-bin-5.0.5.zip
Stop the instance, and create a new AMI for Jenkins to use as a slave (and once I've seen it work delete the old AMI and snapshot).
In my ant build.xml I add the necessary bits to run PMD as part of the test process:


 <path id="test.classpath">
   <path refid="compile.classpath">
   <pathelement location="${test.build.dir}"/>
   <fileset dir="${test.lib.dir}">
     <include name="*.jar">
   </include>
   </fileset>
   <fileset dir="${pmd.path}/lib/">
     <include name="*.jar">
   </include>
   </fileset>
 </path>
...
  <target depends="prepTest, unitTest, integrationTest, pmd" name="test">
...
  <target name="pmd">
    <taskdef classname="net.sourceforge.pmd.ant.PMDTask" 
             classpathref="test.classpath" />
 <pmd>
     <sourcelanguage name="java" version="1.7">
     <ruleset>rulesets/java/basic.xml</ruleset>
     <ruleset>rulesets/java/codesize.xml</ruleset>
     <ruleset>rulesets/java/coupling.xml</ruleset>
     <formatter tofile="${test.reports.dir}/pmd-results-src.xml" type="xml"/>
     <fileset dir="${src.dir}">
       <include name="**/*.java">
       </include>
     </fileset>
 </pmd>
 <pmd>
     <sourcelanguage name="java" version="1.7">
     <ruleset>rulesets/java/basic.xml</ruleset>
     <ruleset>rulesets/java/junit.xml</ruleset>
     <formatter tofile="${test.reports.dir}/pmd-results-testsrc.xml" type="xml">
     <fileset dir="${test.src.dir}">
       <include name="**/*.java">
       </include>
     </fileset>
  </pmd>
</target> 


Note the ${pmd.path} variable in build.xml. This is set up as a system specific config, to allow things to move about. On a development machine these things may be all over the place. In this case a host-specific build.properties file is referenced. However, a file with the hostname in is fundamentally broken when using on-demand EC2 instances for Jenkins - or, more generally, when deploying across multiple similar nodes. In these cases we can call ant with arguments, e.g. ant test -propertyfile jenkins.build.properties. The latter approach doesn't work for NetBeans as I can't find a way to get -propertyfile to be passed in. Because properties cannot be overridden and properties files get loaded first this can be made to work tidily, even with a fallback default properties file as a third option for any properties that have been missed by the argument or host-specific files. The bit of ant config which does this is:
    <exec executable="hostname" outputproperty="computer.hostname">
    <arg value="-s"></arg>
    </exec>
    <property file="${computer.hostname}.build.properties"/>

In Jenkins, add the PMD plugin and in the job configuration tell it how to find the PMD test reports, at test/reports/pmd*.xml
Rebuild.
Cringe at the 1,042 warnings. Mostly some apparently dodgy calls to logging.

No comments:

Post a Comment