7

对于我的一生,我试图让 FindBugs (2.0.1) 作为我的命令行 Ant 构建的一部分运行。我下载了 FindBugs JAR 并将其解压缩到 /home/myuser/java/repo/umd/findbugs/2.0.1/findbugs-2.0.1:

在此处输入图像描述

正如您在屏幕截图中看到的那样,在 /home/myuser/java/repo/umd/findbugs/2.0.1/findbugs-2.0.1/lib 下有一个名为 的 JAR bcel-1.0.jar,如果打开它,您可以看到我已经深入到一个名为org.apache.bcel.classfile.ClassFormatException. 保持这个想法。

然后我将 /home/myuser/java/repo/umd/findbugs/2.0.1/findbugs-2.0.1/lib/findbugs-ant.jar 复制到 ${env.ANT_HOME}/lib 以使其可以访问从命令行运行的 Ant(而不是 Eclipse 内置的 Ant 实例)。

我的项目目录结构如下:

/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/

内部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>

但是当我从命令行运行时ant -buildfile build.xml echoMsg,我在 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!!!

这让我感到惊讶

  • 即使使用failOnError="true",即使遇到此运行时异常,FindBugs 也不会停止构建
  • 最后一段输出“ Output saved to gen/audits/qual/findbugs.html”是骗人的!里面什么都没有gen/audits/qual
  • bcel-1.0.jar绝对位于 FindBugs 的主目录下,就像 lib/ 目录中的所有其他 JAR 一样。

请注意findbugs-ant.jar绝对复制到 ANT_HOME/lib;否则我会得到一个失败的构建,抱怨它找不到 Ant 任务。作为一个健全的检查,我继续这样做(我findbugs-ant.jar从 ANT_HOME/lib 中删除了并且构建失败)。这个构建不会失败(它成功了!)。它只是不运行 findbugs。

谁能发现这里发生了什么?提前致谢!

4

6 回答 6

3

您可以使用 jvm 的 -verbose:class 参数来调试加载 BCEL 的位置。

要将此参数传递给运行 findbugs 的 jvm,请使用 find bugs 插件上的 jvmargs 标志

jvmargs

可选属性。它指定应该传递给用于运行 FindBugs 的 Java 虚拟机的任何参数。如果您正在分析一个非常大的程序,您可能需要使用此属性来指定标志以增加 JVM 可能使用的内存量。

你是如何填充 find bugs lib jar 的?当我下载 findbugs.zip 时,我得到一个 lib 目录,它看起来与您显示的非常不同。特别是,我的包含一个版本为 5.3 的 bcel,而不是您显示的 1.0。

于 2012-10-14T01:09:23.007 回答
1

我的猜测是你实际上在类路径中有两次 BCEL。并且正在从 FindBugs 库之外的 jar 中加载该文件。然后,当 FindBugs 尝试加载 jar 时,它FindBugs 库中找到了 BCEL 并且无法加载它,因为它已经加载了。

解决方案是找到 BCEL 在类路径中的其他位置并将其删除。

于 2012-10-10T18:09:53.410 回答
1

您可能必须定义 AuxClasspath 以包含您的<javac>任务在编译类文件时使用的类路径。

您没有显示编译是如何发生的,所以我假设您创建了一个compile.classapath类路径引用:

<javac destdir="gen/bin/main"
   srcdir="src/main/java"
   classpathref="compile.classpath"/>

<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">
    <auxClasspath refid="compile.classpath"/>
    <sourcePath refid="findbugs.source.path"/>
    <class location="${fb.tmp.jar}"/>
</fb:findbugs>
于 2012-10-10T20:37:35.210 回答
1

我没有从您的 Ant 脚本中看到 bcel 正在登陆 findbugs 任务能够从中加载它的任何类路径。您可能想尝试使您的 taskdef 明确包含 findbugs 需要的所有内容。

<taskdef name="findbugs" classname="edu.umd.cs.findbugs.anttask.FindBugsTask"
    uri="antlib:edu.umd.cs.findbugs">
  <classpath>
    <fileset dir="/home/java/repo/umd/findbugs/2.0.1/findbugs-2.0.1">
      <include name="*.jar"/>
    </fileset>
  </classpath>
</taskdef>
于 2012-10-16T19:53:16.187 回答
1

有趣的是,因为我使用的是相同版本的 Findbugs 并且 jar 文件名为bcel.jarnot bcel-1.0.jar。我也在从Ant脚本运行 Findbugs。尽管听起来很疯狂,但请尝试再次下载 Findbugs,将其解压缩到您当前的位置,然后再次运行您的脚本。

于 2012-10-19T01:03:59.550 回答
0

您可以使用tattle调试大多数类路径问题。它会报告你项目中的所有 jars。所有重复的课程等为我节省了很多时间。

还有准备好蚂蚁任务:http: //docs.jboss.org/tattletale/userguide/1.2/en-US/html/ant.html

于 2012-10-20T10:18:09.393 回答