Sanity4J has been created in order to simplify running ad-hoc static code analysis over Java projects using a standardised set of rules types and priorities.
Various tools are used to conduct the analysis, each with their own set of requirements. Both bytecode and source code are analysed, to ensure the best chance of finding potential problems. Sanity4J presents a single interface to run all the tools and produce a combined report presenting all the findings in a easily accessible manner.
To run the Ant task, you will need the following:
There are two Ant macros that can be run.
Attribute | Description | Required |
---|---|---|
products.dir | The products.dir must point to a directory containing all the tools in use. For example, with a default configuration, these could be spotbugs-3.1.6, pmd-5.0.4, checkstyle-5.6 and jacoco-0.7.9 | Yes |
report.dir | The report output directory. | Yes |
coverage.data.file | The location of a coverage data file (e.g. jacoco.exec for JaCoCo) if you want to include unit testing coverage data in your report. | No |
coverage.merge.data.file | The location of the merged coverage data file. Must be used in conjunction with a list of coverage.data.files nested elements, see below. | No |
external.properties.path | The path location of the sanity4j.properties file. The default is the current directory. | No |
java.runtime | The full path to the java run-time to use. If not specified, "java" is used. | No |
summary.data.file | The location of a (persistent) summary data file if you want to include trend graphs over time. | No |
include.tool.output | If set to "true", the raw tool xml output is also copied into the report directory. This is only useful if there is some other part of your build process that requires it. | No |
Attribute | Description | Required |
---|---|---|
source.path | This element accepts nested Paths / FileSets pointing to the location of the target project's source only. If you have multiple source directories contained within a main directory, you can just list the main directory here - the task will search for all source directories. | Yes |
class.path | This element accepts nested Paths/FileSets pointing to the location of the target project's built classes/jars only. | Yes |
library.path | This element accepts nested Paths / FileSets pointing to the location of jars/classes that the target project depends on. Don't use e.g. an entire local maven repository; only include direct dependencies. | No |
coverage.data.files | This element accepts nested Paths / FileSets pointing to the location of coverage data files to be merged. | No |
configurations | This element accepts nested "configuration" elements describing the "configuration" file passed to the underlying tools. | No |
The source / class / library path will accept Filesets or Paths. If there are multiple source / class directories, it is possible to specify a common parent directory and have the tool find all the nested source/class directories.
The products.dir must point to a directory containing all the tools in use. For example, with a default configuration, these could be spotbugs-3.1.6, pmd-5.0.4, checkstyle-5.6 and cobertura-2.0.1.
The configurations element accepts nested "configuration" elements. "configuration" elements have the following attributes:
Attribute | Description | Required |
---|---|---|
tool | The name of the tool for which the configuration is to be specified ("checkstyle", "spotbugs", "pmd") | Yes |
version | The version of the tool for which the configuration is to be specified. (If no version is specified this configuration will be used by all versions.) | No |
config | The configuration to be used. Usually this is the name of a file passed to the command line of the tool to specify the tool specific configuration. However, this parameter is simply substituted as the value of the $sanity4j.tool.tool.config parameter within the $sanity4j.tool.tool.command parameter that is used to specify the command line of the tool. So the value specified, can be any set of options that make sense at the point of substitution within the $sanity4j.tool.toolcommand. The resource can be a file contained within a jar file on the classpath, or an external file in the file system. If the resource is a jar, then the name is compared with the classpath and the full path to the jar is then passed to the tool instead. | Yes |
Below is a sample XML file with examples for both Ant macros.
<project name="test_sanity4j_ant" default="analyse.test"> <target name="analyse.test" depends="analyse.single, analyse.multi" /> <!-- Run the analysis --> <target name="analyse.single" description="This target runs the QA tools against the given project. The project's coverage task should have been run first."> <!-- Imports --> <typedef resource ="sanity4j-ant.xml" classpath ="target/sanity4j-1.8.2-jar-with-dependencies.jar"/> <!-- Run the Sanity4J QA task --> <sanity4j.run products.dir="target/tools" report.dir="target/sanity4j-ant-report-single" coverage.data.file="target/jacoco.exec"> <source.path> <fileset dir="src/main/java"> <include name="**/*.java"/> </fileset> <fileset dir="src/test/java"> <include name="**/*.java"/> </fileset> </source.path> <class.path> <path path="target/classes"/> <path path="target/test-classes"/> </class.path> <library.path> <path path="target/sanity4j-1.8.2-jar-with-dependencies.jar"/> </library.path> <configurations> <configuration tool="checkstyle" config="local_checkstyle_rules.xml"/> </configurations> </sanity4j.run> </target> <!-- Run the analysis --> <target name="analyse.multi" description="This target runs the QA tools against the given project, merging coverage datafiles. The project's coverage task should have been run first."> <!-- Imports --> <typedef resource ="sanity4j-ant.xml" classpath ="target/sanity4j-1.8.2-jar-with-dependencies.jar"/> <!-- Run the Sanity4J QA task --> <sanity4j products.dir="target/tools" report.dir="target/sanity4j-ant-report-multi" coverage.merge.data.file="target/jacoco.exec"> <source.path> <fileset dir="../sanity4j-test/maven3-multi/child1/src/main/java"> <include name="**/*.java"/> </fileset> <fileset dir="../sanity4j-test/maven3-multi/child1/src/test/java"> <include name="**/*.java"/> </fileset> </source.path> <class.path> <path path="../sanity4j-test/maven3-multi/child1/target/classes"/> <path path="../sanity4j-test/maven3-multi/child1/target/test-classes"/> <path path="../sanity4j-test/maven3-multi/child2/target/classes"/> <path path="../sanity4j-test/maven3-multi/child2/target/test-classes"/> </class.path> <library.path> <path path="target/sanity4j-1.8.2-jar-with-dependencies.jar"/> </library.path> <coverage.data.files> <path path="../sanity4j-test/maven3-multi/child1/target/jacoco.exec"/> <path path="../sanity4j-test/maven3-multi/child2/target/jacoco.exec"/> </coverage.data.files> <configurations> <configuration tool="spotbugs" config="-pluginList local_plugin.jar"/> <configuration tool="pmd" config="local_pmd_rules.xml"/> </configurations> </sanity4j> </target> </project>