FindBugs ディテクターのシンプルサンプル
FindBugs の検出器(Detector)を自作できると、さまざまな応用が利きます。ここではシンプルな FindBugs ディテクターを例示します。
ディテクター作成のために必要となるもの
findbugs.xml
<?xml version="1.0" encoding="UTF-8"?> <FindbugsPlugin xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="findbugsplugin.xsd" pluginid="jp.igapyon.SampleFindBugsDetector" provider="Igapyon project"> <Detector class="jp.igapyon.SampleFindBugsDetector"/> <BugPattern abbrev="SMPL" type="SAMPLE_BUGDETECT001" category="SAMPLE" /> </FindbugsPlugin>
messages.xml
<?xml version="1.0" encoding="UTF-8"?> <MessageCollection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="messagecollection.xsd"> <Plugin> <ShortDescription>FindBugs Sample Plugin</ShortDescription> <Details>Sample FindBugs plugin.</Details> </Plugin> <Detector class="jp.igapyon.SampleFindBugsDetector"> <Details> <![CDATA[ <p> This detector is a simple sample detector. ]]> </Details> </Detector> <BugPattern type="SAMPLE_BUGDETECT001"> <ShortDescription>Sample detector.</ShortDescription> <LongDescription>Sample detect: '{0}' is sample detection.</LongDescription> <Details> <![CDATA[ <p> This is a sample detection. ]]> </Details> </BugPattern> <BugCode abbrev="SMPL">Sample detector.</BugCode> </MessageCollection>
SampleFindBugsDetector.java
package jp.igapyon; import edu.umd.cs.findbugs.BugInstance; import edu.umd.cs.findbugs.BugReporter; import edu.umd.cs.findbugs.OpcodeStack; import edu.umd.cs.findbugs.Priorities; import edu.umd.cs.findbugs.bcel.OpcodeStackDetector; public class SampleFindBugsDetector extends OpcodeStackDetector { private BugReporter bugReporter; public SampleFindBugsDetector(BugReporter bugReporter) { this.bugReporter = bugReporter; } @Override public void sawOpcode(final int seen) { if (seen != INVOKEVIRTUAL) { return; } // インスタンスをともなうメソッド呼び出しを単純にレポートします。 String report = getDottedClassConstantOperand() + "#" + getNameConstantOperand() + "("; if (stack.getStackDepth() > 0) { final OpcodeStack.Item name = stack.getStackItem(0); report += name.getSignature(); } report += ")"; bugReporter.reportBug(new BugInstance(this, "SAMPLE_BUGDETECT001", Priorities.NORMAL_PRIORITY) .addString(report).addClassAndMethod(this).addSourceLine(this)); } }
この例では、比較的高水準な「OpcodeStackDetector」を継承してディテクターを自作しています。用途により、別のクラスを継承することを検討することでしょう。
build.xml
<project> <property name="findbugs.home" value="<<FindBugs の実際の展開後フォルダ>>" /> <taskdef name="findbugs" classname="edu.umd.cs.findbugs.anttask.FindBugsTask"> <classpath> <fileset dir="${findbugs.home}/lib"> <include name="**/*.jar" /> </fileset> </classpath> </taskdef> <target name="runFindbugs"> <findbugs home="${findbugs.home}" output="text" outputFile="findbugs-report.txt"> <class location="<<検査対象としたい *.class ファイルが格納されているフォルダ>>" /> <auxclasspath location="./*.jar" /> </findbugs> </target> <target name="jar"> <delete file="SampleFindBugsDetector.jar" /> <jar destfile="SampleFindBugsDetector.jar"> <fileset dir="./bin"> <include name="**/*.class" /> </fileset> <fileset dir="./"> <include name="findbugs.xml" /> <include name="messages.xml" /> </fileset> </jar> </target> </project>
この jar タスクで作成される「SampleFindBugsDetector.jar」ファイルを findbugs/plugin フォルダにコピーすると、自作ディテクターが FindBugs の検査内容に追加反映されます。
★Eclipse をご利用の方は、「F5」で更新することをお忘れなく。