kelemen / netbeans-gradle-project

This project is a NetBeans plugin able to open Gradle based Java projects. The implementation is based on Geertjan Wielenga's plugin.
172 stars 57 forks source link

Support the Checker Framework #333

Open entonio opened 7 years ago

entonio commented 7 years ago

The Checker Framework is a thorough static analysis tool that can be integrated with NetBeans by means of the Annotation Processing settings in a 'normal' project: https://checkerframework.org/manual/#netbeans

It's imo a much better alternative to what's offered by FindBugs and IDE-specific checkers, none of which have a simple way of doing what should be obvious in my book (everything should be nonnull unless it's annotated as nullable).

However, I haven't found a way to use it with gradle projects. I don't know what changes to the gradle plugin might be needed, but either generic support for settings a processor or a Checker-Framework specific solution would be great for me.

kelemen commented 7 years ago

I don't think (though I might be mistaken) that this requires any support from this plugin. You simply have to add this check to your build as described here: https://checkerframework.org/manual/#gradle

In the document linked above, I would change a couple of things however: It adds the checkerframework dependencies manually and no tool will like that. Instead of that, you should add it to the compileOnly dependencies.

So, assuming you are using Java 8, I would do something like this (completely untested):

configurations {
    checkerFrameworkAnnotatedJDK {
       description = 'a copy of JDK classes with Checker Framework type qualifers inserted'
    }
}

dependencies {
    ... existing dependencies...
    def checkerFrameworkVersion = '2.1.10'
    def jdkVersion = 'jdk8'
    checkerFrameworkAnnotatedJDK "org.checkerframework:${jdkVersion}:${checkerFrameworkVersion}"

    compileOnly "org.checkerframework:checker:${checkerFrameworkVersion}"
    compile "org.checkerframework:checker-qual:${checkerFrameworkVersion}"
}

allprojects {
    tasks.withType(JavaCompile).all { JavaCompile compile ->
        compile.options.compilerArgs = [
                '-processor', 'org.checkerframework.checker.nullness.NullnessChecker',
                // uncomment to turn Checker Framework errors into warnings
                // '-Awarns',
                "-Xbootclasspath/p:${configurations.checkerFrameworkAnnotatedJDK.asPath}"
        ]
    }
}

By the way, I don't think that the Checker Framework is simply to be used instead of FindBugs, since FindBugs is in a different scope. There is no reason not to use both.

entonio commented 7 years ago

Thank you for a quick reply!

I've tried it with your suggestion, but a strange (to me) error occurs:

Malformed class file [plume/OrderedPairIterator.class] in jar [/Users/.../.gradle/caches/modules-2/files-2.1/org.checkerframework/checker/2.1.7/9a158490fff91f405930a7815d94ee25cdc711aa/checker-2.1.7.jar] found on classpath, which means that this class will cause a compile error if referenced in a source file. Gradle 5.0 will no longer allow malformed classes on compile classpath.

and the project doesn't start building.

If, however, I use their suggested

checkerFramework "org.checkerframework:checker:${checkerFrameworkVersion}"

it does build. But all the source 'errors' detected by the Checker Framework are just output to the console (which is what “Enable Annotation Processing” does in a 'normal' project) but not shown on the editor (which is “Enable Annotation Processing in Editor.”), even after calling 'build' (which isn't needed for errors-in-editor in normal projects).

I admit I'm quite out of my depth when it comes to gradle or NB innards, so I don't know where this issue would best be addressed, if it's solvable at all.

kelemen commented 7 years ago

If you do it in the way they said, there is no chance a tool would realize that you have this dependency. There is a workaround which might work (I don't know but there is a chance if NB supports it) and only affects what NB sees but does not affect running Gradle tasks:

if (project.hasProperty('evaluatingIDE') && project.property('evaluatingIDE') == 'NetBeans') {
    configurations {
        compileOnly.extendsFrom checkerFramework
    }
}

Though, I'm not sure what to expect. Does this work with a standard Ant project? Anyway, if explicit support for the checker framework is needed, that requires a separate NB plugin (which can work regardless what build tool you are using).

Also, that warning issued by Gradle seems to me like a real issue. As I remember (many years ago) when I saw the Checker Framework is that it required so many workarounds (and hacks) to use for everything that I didn't bother. I'm personally not even sure if it worth using with the quirks it has. That is too bad because it could be useful.