【问题标题】:FindBugs refuses to find bcel jar on classpathFindBugs 拒绝在类路径上找到 bcel jar
【发布时间】:2012-10-10 18:03:52
【问题描述】:

为了我的一生,我试图让 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 下有一个名为 bcel-1.0.jar 的 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 任务。作为一个健全的检查,我继续这样做(我从 ANT_HOME/lib 中删除了 findbugs-ant.jar 并且构建失败)。这个构建不会失败(它成功了!)。它只是不运行 findbugs。

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

【问题讨论】:

标签: java ant findbugs


【解决方案1】:

您可以使用 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。

【讨论】:

  • 谢谢@sbridges 我会检查一下 - 我正在使用 Ant 1.8.4
  • 我认为您的 bcel 版本错误。如果我下载 findbugs 2.0.1.zip,它包含的 bcel 是 5.0.3
【解决方案2】:

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

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

    • 这是一个很好的建议@Zagrev (+1) 我会在几分钟后试一试。只是出于好奇,是什么让你怀疑是这种情况?我只是问,因为我不会在 1000 年内想到它,而且它是有道理的! (我最近肯定在别处添加了这个 JAR...)
    • 可怕,可怕的经历:)
    • 嗯,这花了一些时间,但我浏览了ANT_HOME/lib 以及我的 FindBugs 主目录下的每个 JAR 文件,bcel-1.0.jar唯一的 包含该类的 JAR。还有其他想法吗??再次感谢!
    【解决方案4】:

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

    你没有展示编译是如何发生的,所以我假设你创建了一个 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>
    

    【讨论】:

    • 感谢@David W. (+1) - 添加了auxClasspath 仍然是同样的错误。我真的觉得 Zagrev 可能一直在使用重复的 JAR 想法,但我似乎找不到它。我想知道,是否有一个工具可以将我的 ANT_HOME/lib 目录指向,并让它打印出该目录中每个 JAR 中每个 Java 类的列表?这样我就可以扫描输出中是否存在重复的 BCEL 类。
    • @pnongrata "那里有一个工具,我可以将我的 ANT_HOME/lib 目录指向,并让它打印出该目录中每个 JAR 中每个 Java 类的列表? " 看看Tattle Tale from JBoss
    【解决方案5】:

    我没有从您的 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>
    

    【讨论】:

      【解决方案6】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-12-17
        • 2011-03-10
        • 2020-06-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多