Sunday, July 2, 2017

PMD source code analyzer

Writing code has been always my liking and passion and today, I came across this code analyzer software called PMD and thought of give it a try. According to PMD,

PMD is a source code analyzer. It finds common programming flaws like unused variables, empty catch blocks, unnecessary object creation, and so forth. It supports Java, JavaScript, Apex, PLSQL, Apache Velocity, XML, XSL.
Additionally it includes CPD, the copy-paste-detector. CPD finds duplicated code in Java, C, C++, C#, PHP, Ruby, Fortran, JavaScript, PLSQL, Apache Velocity, Ruby, Scala, Objective C, Matlab, Python, Go, Swift and Apex.

Damn a lot of languages support I must say, so probably you want to try this as well. As usual, let's get it download and test it. At this writing, I downloaded version 5.5.1 and extracted to a public repository of mine, you can see below. Very intuitive and easy.

 user@localhost:~/videoOnCloud/pmd/pmd-bin-5.5.1$ ./bin/ help  
 help is NOT a valid application name, valid options are:pmd, cpd, cpdgui, designer, bgastviewer  
 Error: Could not find or load main class   
 user@localhost:~/videoOnCloud/pmd/pmd-bin-5.5.1$ ./bin/ pmd help  
 Usage: pmd [options]  
   -failOnViolation, --failOnViolation  
     By default PMD exits with status 4 if violations are found. Disable this  
     option with '-failOnViolation false' to exit with 0 instead and just write the  
     Default: true  
     Specifies the classpath for libraries used by the source code. This is  
     used by the type resolution. Alternatively, a 'file://' URL to a text file  
     containing path elements on consecutive lines can be specified.  
   -benchmark, -b  
     Benchmark mode - output a benchmark report upon completion; default to  
     Default: false  
   -dir, -d  
     Root directory for sources.  
   -encoding, -e  
     Specifies the character set encoding of the source code files PMD is  
     reading (i.e., UTF-8).  
     Default: UTF-8  
     Path to a file containing a list of files to analyze.  
   -format, -f  
     Report format type.  
     Default: text  
   -help, -h, -H  
     Display help on usage.  
     Default: false  
   -language, -l  
     Specify a language PMD should use.  
   -minimumpriority, -min  
     Rule priority threshold; rules with lower priority than configured here  
     won't be used. Default is '5' which is the lowest priority.  
     Default: Low  
     Possible Values: [High, Medium High, Medium, Medium Low, Low]  
     Disable the ruleset compatibility filter. The filter is active by default  
     and tries automatically 'fix' old ruleset files with old rule names  
     Default: false  
   -property, -P  
     {name}={value}: Define a property for the report format.  
     Default: []  
   -reportfile, -r  
     Sends report output to a file; default to System.out.  
  * -rulesets, -R  
     Comma separated list of ruleset names to use.  
     Prints shortened filenames in the report.  
     Default: false  
     Report should show suppressed rule violations.  
     Default: false  
   -stress, -S  
     Performs a stress test.  
     Default: false  
     Specifies the string that marks the a line which PMD should ignore;  
     default is NOPMD.  
     Default: NOPMD  
   -threads, -t  
     Sets the number of threads used by PMD.  
     Default: 1  
   -uri, -u  
     Database URI for sources.  
   -debug, -verbose, -D, -V  
     Debug mode.  
     Default: false  
   -version, -v  
     Specify version of a language PMD should use.  
 Mandatory arguments:  
 1) A java source code filename or directory  
 2) A report format   
 3) A ruleset filename or a comma-delimited string of ruleset filenames  
 For example:   
 C:\>pmd-bin-5.5.1\bin\pmd.bat -d c:\my\source\code -f html -R java-unusedcode  
 Languages and version suported:  
 apex, java, ecmascript, jsp, plsql, vm, xml, xsl, wsdl, pom  
 Available report formats and their configuration properties are:  
   codeclimate: Code Climate integration.  
   csv: Comma-separated values tabular format.  
     problem - Include Problem column  default: true  
     package - Include Package column  default: true  
     file - Include File column  default: true  
     priority - Include Priority column  default: true  
     line - Include Line column  default: true  
     desc - Include Description column  default: true  
     ruleSet - Include Rule set column  default: true  
     rule - Include Rule column  default: true  
   emacs: GNU Emacs integration.  
   html: HTML format  
     linePrefix - Prefix for line number anchor in the source file.  
     linkPrefix - Path to HTML source.  
   ideaj: IntelliJ IDEA integration.  
     classAndMethodName - Class and Method name, pass '.method' when processing a directory.  default:   
     sourcePath - Source path.  default:   
     fileName - File name.  default:   
   summaryhtml: Summary HTML format.  
     linePrefix - Prefix for line number anchor in the source file.  
     linkPrefix - Path to HTML source.  
   text: Text format.  
   textcolor: Text format, with color support (requires ANSI console support, e.g. xterm, rxvt, etc.).  
     color - Enables colors with anything other than 'false' or '0'.  default: yes  
   textpad: TextPad integration.  
   vbhtml: Vladimir Bossicard HTML format.  
   xml: XML format.  
     encoding - XML encoding format, defaults to UTF-8.  default: UTF-8  
   xslt: XML with a XSL Transformation applied.  
     encoding - XML encoding format, defaults to UTF-8.  default: UTF-8  
     xsltFilename - The XSLT file name.  
   yahtml: Yet Another HTML format.  
     outputDir - Output directory.  
 For example on windows:   
 C:\>pmd-bin-5.5.1\bin\pmd.bat -dir c:\my\source\code -format text -R java-unusedcode,java-imports -version 1.5 -language java -debug  
 C:\>pmd-bin-5.5.1\bin\pmd.bat -dir c:\my\source\code -f xml -rulesets java-basic,java-design -encoding UTF-8  
 C:\>pmd-bin-5.5.1\bin\pmd.bat -d c:\my\source\code -rulesets java-typeresolution -auxclasspath commons-collections.jar;derby.jar  
 C:\>pmd-bin-5.5.1\bin\pmd.bat -d c:\my\source\code -f html -R java-typeresolution -auxclasspath file:///C:/my/classpathfile  
 For example on *nix:   
 $ pmd-bin-5.5.1/bin/ pmd -dir /home/workspace/src/main/java/code -f html -rulesets java-basic,java-design  
 $ pmd-bin-5.5.1/bin/ pmd -d ./src/main/java/code -f xslt -R java-basic,java-design -property xsltFilename=my-own.xsl  
 $ pmd-bin-5.5.1/bin/ pmd -d ./src/main/java/code -f html -R java-typeresolution -auxclasspath commons-collections.jar:derby.jar  
 Was passed main parameter 'help' but no main parameter was defined  
 user@localhost:~/videoOnCloud/pmd/pmd-bin-5.5.1$ ./bin/ pmd -d ../../src/java/play/learn/tomcat/ -version 1.7 -language java -R java-unusedcode  
 user@localhost:~/videoOnCloud/pmd/pmd-bin-5.5.1$ ./bin/ pmd -d ../../src/java/play/learn/tomcat/ -version 1.7 -language java -R java-basic,java-design  
 /home/user/videoOnCloud/src/java/play/learn/tomcat/   All methods are static. Consider using a utility class instead. Alternatively, you could add a private constructor or make the class abstract to silence this warning.  
 /home/user/videoOnCloud/src/java/play/learn/tomcat/   Private field 'endpoint' could be made final; it is only initialized in the declaration or constructor.  
 /home/user/videoOnCloud/src/java/play/learn/tomcat/   Document empty method body  
 /home/user/videoOnCloud/src/java/play/learn/tomcat/   Document empty method body  
 /home/user/videoOnCloud/src/java/play/learn/tomcat/   Avoid if (x != y) ..; else ..;  

So I tried a few rulesets on my java codes and report shown accordingly. This code analyzer definitely serve as a good helper for code learner. You can actually use PMD various way. Some common ways I use often

via command line
via ant
via mvn
via jenkins ci

You asked, what other rules can I use? well, for java, you can read more here. There are also other rules for each language. Last but not least, you can get the above code here.

1 comment:

  1. Do you know how to edit the template of the ouput file it makes. Right now I have it set to html and I want to change the formatting a bit. Any ideas?