##### Overview

- Download PMD 4.2.5
- What's new in PMD 4.2.5
- PMD in the news
- PMD-related products and books
- Best practices
- Future directions
- Similar projects
- Credits
- License
- What does 'PMD' mean?

##### Usage

- Installation
- Command line usage
- Ant task usage
- Maven plugin usage
- Mvn plugin usage
- IDE plugin usage
- Suppressing warnings
- Finding duplicated code
- JSP support

##### Customizing PMD

- Compiling PMD
- How to write a rule
- Writing XPath rules
- How to make a rule set
- How it works
- Rule guidelines

##### For example

- Run PMD on a Sourceforge project

##### Rule Sets

- Index
- Android
- Basic
- Braces
- Code Size
- Clone
- Controversial
- Coupling
- Design
- Finalizers
- Import Statements
- J2EE
- Javabeans
- JUnit Tests
- Logging (Java)
- Logging (Jakarta)
- Migrating
- Naming
- Optimizations
- Strict Exceptions
- Strings
- Sun Security
- Unused Code
- Java Server Pages
- Java Server Faces

##### Project Documentation

- About
- Project Info
- Project Reports
- Development Process

##### Legend

- External Link
- Opens in a new window

## Jakarta Commons Logging Rules

The Jakarta Commons Logging ruleset contains a collection of rules that find questionable usages of that framework.

### UseCorrectExceptionLogging

Since: PMD 3.2

To make sure the full stacktrace is printed out, use the logging statement with 2 arguments: a String and a Throwable.

This rule is defined by the following XPath expression:

    //CatchStatement/Block/BlockStatement/Statement/StatementExpression
    /PrimaryExpression[PrimaryPrefix/Name[starts-with(@Image,
    concat(ancestor::ClassOrInterfaceDeclaration/ClassOrInterfaceBody/ClassOrInterfaceBodyDeclaration/FieldDeclaration
    [Type//ClassOrInterfaceType[@Image='Log']]
    /VariableDeclarator/VariableDeclaratorId/@Image, '.'))]]
    [PrimarySuffix/Arguments[@ArgumentCount='1']]
    [PrimarySuffix/Arguments//Name/@Image = ancestor::CatchStatement/FormalParameter/VariableDeclaratorId/@Image]

Example:

    public class Main {
     private static final Log _LOG = LogFactory.getLog( Main.class );
     void bar() {
      try {
      } catch( Exception e ) {
       _LOG.error( e ); //Wrong!
      } catch( OtherException oe ) {
       _LOG.error( oe.getMessage(), oe ); //Correct
      }
     }
    }

### ProperLogger

Since: PMD 3.3

A logger should normally be defined private static final and have the correct class. Private final Log log; is also allowed for rare cases where loggers need to be passed around, with the restriction that the logger needs to be passed into the constructor.

This rule is defined by the following XPath expression:

    //ClassOrInterfaceBodyDeclaration[FieldDeclaration//ClassOrInterfaceType[@Image='Log']
     and
     not(FieldDeclaration[@Final='true'][@Static='true'][@Private='true'][.//VariableDeclaratorId[@Image=$staticLoggerName]]
     //ArgumentList//ClassOrInterfaceType/@Image = ancestor::ClassOrInterfaceDeclaration/@Image)
     and
     not(FieldDeclaration[@Final='true'][@Private='true'][.//VariableDeclaratorId[@Image='log']]
     [count(.//VariableInitializer)=0]
     [ancestor::ClassOrInterfaceBody//StatementExpression[.//PrimaryExpression/descendant::*[@Image='log']][count(.//AllocationExpression)=0]]
     )]

Example:

     public class Foo {
     // right
      private static final Log LOG = LogFactory.getLog(Foo.class);
     // wrong
     protected Log LOG = LogFactory.getLog(Testclass.class);
    }

This rule has the following properties:

Name | Default value | Description
staticLoggerName |  |