I installed the Fedora 20 findbugs RPMs, and set up my Ant build.xml
file thusly:
<property name="findbugs.home" location="/usr/share/findbugs"/>
<target name="findbugs" description="static bytecode analysis">
<taskdef name="findbugs" classname="edu.umd.cs.findbugs.anttask.FindBugsTask">
</taskdef>
<findbugs home="${findbugs.home}" output="xml" outputFile="bcel-fb.xml">
<sourcePath path="${src.dir}"/>
<fileset dir="${build.dir}">
<include name="**/*.class"/>
</fileset>
</findbugs>
</target>
This gives me the error:
java.lang.IllegalArgumentException: Can't find findbugs.jar in /usr/share/findbugs/lib
So I make /usr/share/findbugs/lib
a symbolic link to /usr/share/java
, where findbugs.jar
lives. That gets me a bit further, but now it spits out:
findbugs:
[findbugs] Executing findbugs from ant task
[findbugs] Running FindBugs...
[findbugs] Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/bcel/classfile/ClassFormatException
strace
shows that it found and opened /usr/share/java/findbugs-bcel.jar
, so I have no idea why it can't load the class. Explicitly adding /usr/share/java/findbugs-bcel.jar
to the taskdef's classpath doesn't change anything.
NOTE: I'm not trying to run FindBugs on BCEL. BCEL is used by FindBugs to do its analysis, and my own code doesn't use BCEL at all.
You need an <Auxclasspath/>
subentity pointing to the classpath you used when you compiled. Findbugs uses the built *.class
files, and needs the source to pinpoint in the source code where an error is, the classes you're analyzing, and the classpath to all of your third party jars to be able to understand the code:
<findbugs
home="${findbugs.home}"
output="xml"
outputFile="bcel-fb.xml">
<auxClasspath refid="main.classpath"/> <!-- Third party jars classpath -->
<class location="${main.destdir}"/> <!-- Class files you're analyzing -->
<sourcePath path="${main.srcdir}"/> <!-- Source directory -->
</findbugs>
By the way, you should put the findbugs jar inside your project (My preference would be under ${basedir}/antlib/findbugs
) and use that in your <taskdef/>
:
<taskdef name="findbugs"
classname="edu.umd.cs.findbugs.anttask.FindBugsTask">
<classpath>
<fileset dir="${basedir}/antlib/findbugs"/>
</classpath>
</taskdef>
This way, Findbugs is part of your project. Anyone who checks out your project will automatically have the findbugs jar and will be able to run your findbugs task without having to download the jar and installing it in $ANT_HOME/lib
.
I do this with any optional Ant task jars like PMD, Checkstyle, and Ant-Contrib. It makes it much easier for others to be able to run my builds, and I spend less time trying to explain to people where they can get that jar, and how to install it. Plus, if you use a Continuous Build system like Jenkins, you don't have to futz with the server anytime you add in a new optional jar.
Try using this,
Adding task definition
<taskdef name="findbugs" classname="edu.umd.cs.findbugs.anttask.FindBugsTask"/>
Defining target
<property name="findbugs.home" value="/export/home/daveho/work/findbugs" />
<target name="findbugs" depends="jar">
<findbugs home="${findbugs.home}"
output="xml"
outputFile="bcel-fb.xml" >
<auxClasspath path="${basedir}/lib/Regex.jar" />
<sourcePath path="${basedir}/src/java" />
<class location="${basedir}/bin/bcel.jar" />
</findbugs>
</target>
This target will execute FindBugs on bcel.jar, which is the Jar file produced by BCEL's build script. (By making it depend on the "jar" target, we ensure that the library is fully compiled before running FindBugs on it.) The output of FindBugs will be saved in XML format to a file called bcel-fb.xml. An auxiliary Jar file, Regex.jar, is added to the aux classpath, because it is referenced by the main BCEL library. A source path is specified so that the saved bug data will have accurate references to the BCEL source code.
For more info.
If findbugs is not located at:
<property name="findbugs.home" location="/usr/share/findbugs"/>
I would change your Ant Findbugs config to the location of the Findbug library files:
<property name="findbugs.home" location="/usr/share/java"/>
Or even,
<property name="findbugs.home" location="/usr/share/java/findbugs"/>
is this is the directory.
It does look like a classpath issue.
According to Richard Fearn [1] Fedora repackages findbugs jars and modifies the way the FB library classes are loaded, so by using findbugs from fedora one must use workaround described below. See also [2] for the original bug request at findbugs.
Quote from [1]:
As a workaround it's possible to do this:
<findbugs classpath="/usr/share/java/findbugs.jar:/usr/share/java/ant/ant-findbugs.jar:/usr/share/java/apache-commons-lang.jar:/usr/share/java/dom4j.jar:/usr/share/java/findbugs-bcel.jar:/usr/share/java/jaxen.jar:/usr/share/java/jcip-annotations.jar:/usr/share/java/jFormatString.jar:/usr/share/java/jsr-305.jar:/usr/share/java/junit.jar:/usr/share/java/objectweb-asm/asm.jar:/usr/share/java/objectweb-asm/asm-commons.jar:/usr/share/java/objectweb-asm/asm-tree.jar">
where that classpath is the output from:
$ build-classpath
cat /etc/ant.d/findbugs
[1] https://bugzilla.redhat.com/show_bug.cgi?id=1080682#c4
[2] https://sourceforge.net/p/findbugs/bugs/1255/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With