如何在Checker FrameWork中显示包含行号等的完整编译错误消息信息

时间:2017-04-07 11:34:22

标签: checker-framework

我刚刚开始使用Checker Framework,并且在这个框架的作者的一个示例项目中存在一个完全可重现的问题。这个项目在这里可用: https://github.com/typetools/checker-framework/tree/master/docs/examples/GradleExamples

当我从root运行此命令时:

>gradle compileJava

我收到这个编译输出:

       public static /*@Nullable*/ Object nullable = null;
                                                  ^

  required: @Initialized @NonNull Object

        list.add(null); // error on this line
                 ^

  required: @Initialized @NonNull String
2 errors
:compileJava FAILED

正如您所看到的,没有任何关于错误发生的信息,如类名,代码中的行号等。 我在他们的官方手册中没有找到任何可以适当改变输出格式的编译器参数的信息。我希望错误消息看起来像这样:

~\GradleExample.java:33 error: ';' expected

更新:

我在3台机器上实现了这种行为:

    • 操作系统:Microsoft Windows 7 x64 Ultimate SP1 [版本6.1.7601];
    • Java:1.8.0_73;
    • Gradle:2.14。
    • 操作系统:Microsoft Windows 10 x64 Pro [版本10.0.14393];
    • Java:1.8.0_121;
    • Gradle:3.4.1。
    • 操作系统:Microsoft Windows 7 x64 Ultimate SP1 [版本6.1.7601];
    • Java:1.8.0_121;
    • Gradle:3.4.1。
  1. 只有在使用Gradle运行时才会出现行号和类名的缺失。我还尝试使用Maven和Javac从命令行运行检查程序,它运行良好 要使用Gradle i配置Checker Framework,请按照手动中的步骤操作。有3个步骤:

    1. 下载框架;
    2. 解压缩以创建一个checker-framework目录;
    3. 配置Gradle以在类路径中包含Checker Framework。
    4. 据我了解,当通过依赖关系管理提供所需的Checker Framework的jar时,Gradle将自动执行步骤1和2。不过我尝试了两种选择:

      1. 依赖管理:
        我只是下载了示例项目并执行了#34; gradle compileJava"从根 GradleJava7Example项目。
      2. 在gradle构建文件中手动编写路径:
      3.  
            allprojects {
        
                tasks.withType(JavaCompile).all { JavaCompile compile ->
        
                    compile.options.compilerArgs = [
                    '-processor', 'org.checkerframework.checker.nullness.NullnessChecker',
                    '-processorpath', "C:\\checker-framework-2.1.10\\checker\\dist\\checker.jar",
                    "-Xbootclasspath/p:C:\\checker-framework-2.1.10\\checker\\dist\\jdk8.jar",
                    '-classpath', 'C:\\checker-framework-2.1.10\\checker\\dist\\checker.jar;C:\\checker-framework-2.1.10\\checker\\dist\\javac.jar'
                    ]
                }
            }
        

1 个答案:

答案 0 :(得分:0)

我找到了解决方法。我稍后会解释它,但现在如果有人遇到同样的问题,请将此行添加到JavaCompile任务配置中:

allprojects {
    tasks.withType(JavaCompile).all { JavaCompile compile ->

        System.setProperty("line.separator", "\n")  // <<<<<< add this line

        compile.options.compilerArgs = [
            '-processor', 'org.checkerframework.checker.nullness.NullnessChecker',
            '-processorpath', "${configurations.checkerFramework.asPath}",
            "-Xbootclasspath/p:${configurations.checkerFrameworkAnnotatedJDK.asPath}"
        ]
    }
}

首先,我必须说问题根本不在Checker Framework中。我设法重现了与没有Checker Framework的问题中提到的相同的行为。我创建了一个小的自定义注释处理器。这是代码:

@SupportedSourceVersion(value = SourceVersion.RELEASE_8)
@SupportedAnnotationTypes(value = {"*"})
public class MyProcessor extends AbstractProcessor{

    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        String sepr = System.getProperty("line.separator");

        processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "[error code] " + sepr + " catched!!!");

        return true;
    }

}

正如您所看到的,它只是在开始时打印一条消息。请注意,我使用java.lang.System类提供的行分隔符来拆分消息。当我注册这个处理器并试图运行&#34; gradle compileJava&#34;从gradle项目中它产生了以下输出:

:compileJava

    catched!!!

1 error
:compileJava FAILED

该物业&#34; line.separator&#34;对于Windows操作系统,返回CR + LF:&#34; \ r \ n&#34;。我不知道为什么Messager.printMessage(Diagnostic.Kind kind, CharSequence msg)有这种行为,因为当我输入System.err.print("[error code] " + sepr + " catched!!!")时,一切正常(请注意,只有当我使用Gradle时,如果我手动运行javac,则会出现此问题所有论点或使用Maven就好了。) 我发现,如果我用系统分隔符提供的简单&#34; \ n&#34;符号编译器错误消息正确显示。 现在我选择这个解决方案作为解决方法。