Uploaded image for project: 'Grails'
  1. Grails
  2. GRAILS-9018

PMD Ant task error when using rules from rulesets directory


    • Type: Bug Bug
    • Status: Open
    • Priority: Major Major
    • Resolution: Unresolved
    • Affects Version/s: 2.0.3
    • Fix Version/s: None
    • Component/s: None
    • Labels:


      This is the same problem that Gradle fixed: http://issues.gradle.org/browse/GRADLE-632.

      I have CodeNarc plugin installed, and need to run PMD as well, to check the Java code that's part of our project.

      I created a GANT script and used AntBuilder to call PMD:

      outputDir = 'target/test-reports/pmd'



      Ant.taskdef(name:"pmd", classname:"net.sourceforge.pmd.ant.PMDTask")
      formatter(type:"xml", tofile:"${outputDir}

      formatter(type:"html", tofile:"$

      fileset(dir:"src/java"){ include(name:"**/*.java") }

      Unfortunately this causes an exception:
      Error Error executing script Pmd: : java.lang.ClassCastException: org.codenarc.rule.basic.AssertWithinFinallyBlockRule cannot be cast to net.sourcef

      Digging into this, it appears PMD looks in the classpath for rulesets, and because PMD and CodeNarc both keep their ruleset files in the same dir "rulesets", we have a problem. If you choose name of the ruleset that exists in PMD but doesn't exist in CodeNarc (like "clone.xml") than everything works fine, PMD picks the right file.

      A deeper issue here is that it appears I can't change the classpath that the Ant task runs under? I created an ant path with just the PMD jar on it, and set that using the classpath element on the taskdef. It seems to use that only to find the task, not to find the rulesetfiles or run the actual task???

      ant.path(id: "pmdJar")
      { pathelement(location: "C:/Users/david/.grails/ivy-cache/pmd/pmd/jars/pmd-4.3.jar") }

      Ant.taskdef(name:"pmd", classname:"net.sourceforge.pmd.ant.PMDTask", classpathref:"pmdJar")
      formatter(type:"xml", tofile:"${outputDir}

      formatter(type:"html", tofile:"$



      { include(name:"**/*.java") }


      If I set the classname to something incorrect, I get the expected error, and the classpath it is looking for the task on:

      Error Error executing script Pmd: : taskdef class net.sourceforge.pmd.ant.PMDTas cannot be found using the classloader AntClassLoader[C:\Users\david\.grails\ivy-cache\pmd\pmd\jars\pmd-4.3.jar]

      As expected.

      However, it doesn't seem to use the classpath when it actually executes the Ant.pmd? Which classpath does it use for that? And how can it be referenced?

      I changed the classpath to include the temp dir, added the my own rules.xml in the temp dir, and specified rulesetfiles. PMD looks on the classpath for these files, the documentation suggesting it uses the classpath specified in the task. However, when I run this, it throws an error, and this time specifies a completely different classpath:

      Error Error executing script Pmd: : Can't find resource myruleset.xml. Make sure the resource is a valid file or URL or is on the CLASSPATH. Here's the
      current classpath: c:\grails-2.0.3\lib\org.codehaus.groovy\groovy-all\jars\groovy-all-1.8.6.jar;c:\grails-2.0.3\dist\grails-bootstrap-2.0.3.jar


        There are no comments yet on this issue.


          • Assignee:
            David Hay
          • Votes:
            0 Vote for this issue
            0 Start watching this issue


            • Created: