Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FindBugs refuses to find bcel jar on classpath

Tags:

java

ant

findbugs

For the life of me, I am trying to get FindBugs (2.0.1) to run as part of my command-line Ant build. I downloaded the FindBugs JAR and extracted it to /home/myuser/java/repo/umd/findbugs/2.0.1/findbugs-2.0.1:

enter image description here

As you can see in the screenshot, under /home/myuser/java/repo/umd/findbugs/2.0.1/findbugs-2.0.1/lib there is a JAR called bcel-1.0.jar, and if you open it, you can see that I have drilled down to a class called org.apache.bcel.classfile.ClassFormatException. Hold that thought.

I then copied /home/myuser/java/repo/umd/findbugs/2.0.1/findbugs-2.0.1/lib/findbugs-ant.jar to ${env.ANT_HOME}/lib to make it accessible to the version of Ant that is ran from the command-line (instead of the Ant instance that comes built-into Eclipse).

My project directory structure is as follows:

/home/myuser/sandbox/workbench/eclipse/workspace/myapp/
    src/
        main/
            java/
        test/
            java/
    build/
        build.xml
        build.properties
    gen/
        bin/
            main/ --> where all main Java class files compiled to
            test/ --> where all test Java class files compiled to
        audits/
            qual/
        staging/

Inside build.xml:

<project name="myapp-build" basedir=".." default="package"
    xmlns:fb="antlib:edu.umd.cs.findbugs">

    <path id="findbugs.source.path">
        <fileset dir="src/main/java">
            <include name="**.*java"/>
        </fileset>
        <fileset dir="src/main/test">
            <include name="**.*java"/>
        </fileset>
    </path>

    <taskdef name="findbugs" classname="edu.umd.cs.findbugs.anttask.FindBugsTask"
        uri="antlib:edu.umd.cs.findbugs"/>

    <!-- Other Ant target omitted for brevity. -->

    <target name="run-findbugs">
        <!-- Create a temp JAR that FindBugs can use for analysis. -->
        <property name="fb.tmp.jar" value="gen/staging/${ant.project.name}-findbugs-temp.jar"/>
        <echo message="Creating ${fb.tmp.jar} for FindBugs."/>
        <jar destfile="gen/staging/${ant.project.name}-findbugs-temp.jar">
            <fileset dir="gen/bin/main" includes="**/*.class"/>
            <fileset dir="gen/bin/test" includes="**/*.class"/>
        </jar>

        <echo message="Conducting code quality tests with FindBugs."/>
        <fb:findbugs home="/home/myuser/java/repo/umd/findbugs/2.0.1/findbugs-2.0.1"
            output="html" outputFile="gen/audits/qual/findbugs.html" stylesheet="fancy-hist.xsl" failOnError="true">
            <sourcePath refid="findbugs.source.path"/>
            <class location="${fb.tmp.jar}"/>
        </fb:findbugs>
    </target>

    <target name="echoMsg" depends="run-findbugs">
        <echo message="The build is still alive!!!"/>
    </target>
</project>

But when I run ant -buildfile build.xml echoMsg from the command-line, I get an error in FindBugs:

run-findbugs:
    [echo] Creating gen/staging/myapp-build-findbugs-temp.jar for FindBugs.
    [jar] Building jar: /home/myuser/sandbox/workbench/eclipse/workspace/myapp/gen/staging/myapp-build-findbugs-temp.jar
    [echo] Conducting code quality tests with FindBugs.
[fb:findbugs] Executing findbugs from ant task
[fb:findbugs] Running FindBugs...
[fb:findbugs] Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/bcel/classfile/ClassFormatException
[fb:findbugs] Caused by: java.lang.ClassNotFoundException: org.apache.bcel.classfile.ClassFormatException
[fb:findbugs]   at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
[fb:findbugs]   at java.security.AccessController.doPrivileged(Native Method)
[fb:findbugs]   at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
[fb:findbugs]   at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
[fb:findbugs]   at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
[fb:findbugs]   at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
[fb:findbugs] Could not find the main class: edu.umd.cs.findbugs.FindBugs2.  Program will exit.
[fb:findbugs] Java Result: 1
[fb:findbugs] Output saved to gen/audits/qual/findbugs.html

echoMsg:
    [echo] The build is still alive!!!

Here's what has me amazed:

  • Even with failOnError="true", FindBugs is not halting the build even when this runtime exception is encountered
  • The last piece of output "Output saved to gen/audits/qual/findbugs.html" is a lie! There is nothing in gen/audits/qual!
  • The bcel-1.0.jar is absolutely under FindBugs home, just like every other JAR in the lib/ directory.

Please note: the findbugs-ant.jar is definitely copied to ANT_HOME/lib; otherwise I would be getting a failed build complaining that it couldn't find the Ant tasks. As a sanity check, I went ahead and did this (I deleted the findbugs-ant.jar from ANT_HOME/lib and got a failed build). This build doesn't fail (it succeeds!). It just doesn't run findbugs.

Can anyone spot what is going on here? Thanks in advance!

like image 282
IAmYourFaja Avatar asked Oct 10 '12 18:10

IAmYourFaja


2 Answers

You can debug where BCEL is being loaded from using the -verbose:class argument to the jvm.

To pass this argument to the jvm running findbugs, use the jvmargs flag on the find bugs plugin

jvmargs

Optional attribute. It specifies any arguments that should be passed to the Java virtual machine used to run FindBugs. You may need to use this attribute to specify flags to increase the amount of memory the JVM may use if you are analyzing a very large program.

How did you populate the find bugs lib jar? When I download findbugs.zip, I get a lib directory which looks very different than what you show. In particular, mine contains a bcel with a version of 5.3, not 1.0 as you show.

like image 100
sbridges Avatar answered Sep 21 '22 05:09

sbridges


Funny thing because I am using the same version of Findbugs and the jar file is named bcel.jar not bcel-1.0.jar. I am also running Findbugs from an Ant script. As crazy as it might sound, try to download the Findbugs once again, unpack it in the place of your current one and run your script once again.

like image 38
Jagger Avatar answered Sep 23 '22 05:09

Jagger