我刚刚开始使用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台机器上实现了这种行为:
只有在使用Gradle运行时才会出现行号和类名的缺失。我还尝试使用Maven和Javac从命令行运行检查程序,它运行良好 要使用Gradle i配置Checker Framework,请按照手动中的步骤操作。有3个步骤:
据我了解,当通过依赖关系管理提供所需的Checker Framework的jar时,Gradle将自动执行步骤1和2。不过我尝试了两种选择:
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'
]
}
}
答案 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;符号编译器错误消息正确显示。
现在我选择这个解决方案作为解决方法。