Each checker is associated with a XML description which contains the name, description, class name, etc. When Arana runs, it will read the XML description and dynamically load the checker. So let us start with the format of the XML description. We will use the checker that checks "empty catch block" as an example:
<checker name="EmptyCatchBlock" message="Avoid empty catch blocks" class="edu.ksu.cis.projects.arana.checkers.basic.EmptyCatchBlock"> <description> Empty Catch Block finds instances where an exception is caught, but nothing is done. In most circumstances, this swallows an exception which should either be acted on or reported. </description> <priority>NORMAL_PRIORITY</priority> <example> .... </example> </checker>
After finishing the XML description, we proceed to write the checker. The checker should extend edu.ksu.cis.projects.arana.AbstractJavaSourceChecker and the checker class name (including package) should be the same as in the XML description. So for the "empty catch block" example, it starts with
package edu.ksu.cis.projects.arana.checkers.basic; public class EmptyCatchBlock extends AbstractJavaSourceChecker
public boolean visit(TryStatement node) { List<CatchClause> catches = (List<CatchClause>)node.catchClauses(); for (CatchClause c : catches) { if (c.getBody().statements().isEmpty()) { ctx.getReport().addViolation( createViolation(ctx, getLineno(c.getStartPosition()), getMessage())); } } return true; }