Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
# Mobile Tools for Java (J2ME)
.mtj.tmp/

# Package Files #
# Package files
*.jar
*.war
*.nar
Expand All @@ -19,7 +19,7 @@
*.tar.gz
*.rar

# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
# Virtual machine crash logs; see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
replay_pid*

Expand Down
81 changes: 42 additions & 39 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@ plugins {
If you are upgrading from plugin version 0.x to 1.x, see the [migration
guide](#migrating-from-0x-to-1x).

The plugin supports Gradle versions 7.3 and above, which requires Java 17 and
above. Although you must compile your project using at least Java 17, the
compiled classfiles can be compatible with, and can run on, any version of Java.
The plugin supports Gradle version 7.3 and later, and it requires Java 17 or
later. Although you must compile your project using at least Java 17, the
compiled class files can be compatible with, and can run on, any version of
Java.

The plugin is compatible with Gradle's [configuration
cache](https://docs.gradle.org/current/userguide/configuration_cache.html).
Expand All @@ -32,7 +33,7 @@ You must specify which
[version](https://github.com/typetools/checker-framework/releases) of the
Checker Framework to use.

* The Gradle developers recommend to modify two files. Add this to `build.gradle`:
* The Gradle developers recommend modifying two files. Add this to `build.gradle`:

```groovy
checkerFramework {
Expand All @@ -47,24 +48,25 @@ Checker Framework to use.
checker-framework = "org.checkerframework:checker:4.2.3"
```

* Alternately, you can edit just one file. Add this to `build.gradle`:
* Alternatively, you can edit just one file. Add this to `build.gradle`:

```groovy
checkerFramework {
version = "4.2.3"
}
```

The special value **"local"** means to use a locally-built version of the
Checker Framework, found at environment variable `$CHECKERFRAMEWORK`.
The special value **"local"** means to use a locally built version of the
Checker Framework, in the directory named by the `CHECKERFRAMEWORK` environment
variable.

The command-line argument **`-PcfVersion=...`** (where "..." is a version number
or "local") overrides settings in gradle buildfiles.
or "local") overrides settings in Gradle build files.

#### Checker Framework jar files

Alternately, you can directly specify which checker and checker-qual jars to
use. You must also set the Checker Framework version to the special value
Alternatively, you can directly specify which checker and checker-qual jar files
to use. You must also set the Checker Framework version to the special value
**`"dependencies"`**. Put the following in your `build.gradle` file:

```groovy
Expand All @@ -86,7 +88,8 @@ dependencies {

### Which checkers to run

You must specify which checkers to run using `checkerFramework.checkers` property.
You must specify which checkers to run, using the `checkerFramework.checkers`
property.

For example, using Groovy syntax in a `build.gradle` file:

Expand Down Expand Up @@ -159,9 +162,9 @@ checkerFramework {
}
```

From the command line, add `-PskipCheckerFramework` to your gradle invocation. You can also pass
`-PskipCheckerFramework=false` to enable the Checker Framework even if the configuration has
`skipCheckerFramework = true`.
From the command line, add `-PskipCheckerFramework` to your Gradle invocation.
You can also pass `-PskipCheckerFramework=false` to enable the Checker Framework
even if the configuration has `skipCheckerFramework = true`.

### Disabling the Checker Framework for tests

Expand Down Expand Up @@ -232,12 +235,12 @@ for different subprojects (for instance, if you want to run different checkers).

## Modules

The Checker Framework inserts inferred annotations into bytecode even if none
appear in source code, so you must make them known to the compiler even if you
write no annotations in your code. When running the plugin on a Java project
that uses modules, you need to add annotations to the module path.
When running the plugin on a Java project that uses modules, you need to add the
annotations to the module path. This is necessary even if you write no
annotations in your code, because the Checker Framework inserts inferred
annotations into the bytecode.

Add following to your `module-info.java`:
Add the following to your `module-info.java`:

```java
requires org.checkerframework.checker.qual;
Expand All @@ -246,7 +249,7 @@ requires org.checkerframework.checker.qual;
The addition of `requires` is typically enough.

If it does not fix your compilation issues, you can additionally add the `checker-qual.jar`
artifact (which only contains annotations) to the module path:
artifact (which contains only annotations) to the module path:

```groovy
checkerFramework {
Expand All @@ -264,36 +267,36 @@ the [Lombok Gradle Plugin](https://plugins.gradle.org/plugin/io.freefair.lombok)
to delombok your source code before it is passed to the Checker Framework
for type-checking. This plugin does not support any other use of Lombok.

For the Checker Framework to work properly on delombok'd source code,
For the Checker Framework to work properly on delomboked source code,
you must include the following key in your project's `lombok.config` file:

```config
lombok.addLombokGeneratedAnnotation = true
```

By default, Lombok suppresses all warnings in the code it generates. If you
want to typecheck the code that Lombok generates, set the `addSuppressWarnings`
to false:
want to typecheck the code that Lombok generates, set `addSuppressWarnings` to
false:

```config
lombok.addSuppressWarnings = false
```

Note that doing so will cause *all* tools (including Javac itself) to begin issuing
Note that doing so will cause *all* tools (including javac itself) to begin issuing
warnings in the code that Lombok generates.

## Using a locally-built plugin
## Using a locally built plugin

To use a locally-modified version of this plugin:
To use a locally modified version of this plugin:

1. Publish the plugin to your local Maven repository:

```sh
./gradlew publishToMavenLocal
```

2. Add the following to the `settings.gradle` file in
the Gradle project that you want to use the plugin:
2. Add the following to the `settings.gradle` file of the Gradle project in
which you want to use the plugin:

```groovy
pluginManagement {
Expand Down Expand Up @@ -328,7 +331,7 @@ you need to make some changes in order to use version 1.x.
to configure interaction with Lombok.

* **`skipVersionCheck`**: There is no longer a version check that might cause
"zip file too large" error. Remove the `-PskipVersionCheck` command-line
a "zip file too large" error. Remove the `-PskipVersionCheck` command-line
argument and remove Gradle code like

```groovy
Expand All @@ -337,34 +340,34 @@ you need to make some changes in order to use version 1.x.
}
```

* **`cfLocal`**: Set the version to `"local"` to use a locally-built version
* **`cfLocal`**: Set the version to `"local"` to use a locally built version
of the Checker Framework. Change command-line argument `-PcfLocal` to
`-PcfVersion=local`. (Note: The `cfLocal` functionality was not an
official part of the plugin, but a number of projects use it.)

4. If you want to use a non-standard Checker Framework jar file (such as that of
eisop) see [Checker Framework jar files](#checker-framework-jar-files).
4. If you want to use a nonstandard Checker Framework jar file (such as that of
eisop), see [Checker Framework jar files](#checker-framework-jar-files).

## Troubleshooting

### ClassCastException for a javac class

If you encounter a crash with a `ClassCastException` referencing some internal
Javac class, disable incremental compilation in your build using the following
javac class, disable incremental compilation in your build using the following
code in your `checkerFramework` configuration block:

```groovy
checkerFramework {
incrementalize = false
}
checkerFramework {
incrementalize = false
}
```

Background: By default, the plugin assumes that all checkers are ["isolating
incremental annotation
processors"](https://docs.gradle.org/current/userguide/java_plugin.html#sec:incremental_annotation_processing).
This assumption speeds up builds by enabling incremental compilation. Gradle's
documentation warns that incremental compilation with the Checker Framework
plugin (or any other plugin that uses internal Javac APIs) may crash, because
plugin (or any other plugin that uses internal javac APIs) may crash, because
Gradle wraps some of those APIs.

### Incompatibility with Error Prone 2.3.4 and earlier
Expand All @@ -374,9 +377,9 @@ you need to use Error Prone version 2.4.0 (released in May 2020) or later.

<!--
LocalWords: JavaCompile gradle checkerframework checkerFramework toml lombok
LocalWords: PcfVersion buildfiles qual eisopVersion eisop1 checkerQual config
LocalWords: PcfVersion qual eisopVersion eisop1 checkerQual config delomboked
LocalWords: kotlin CheckerFrameworkExtension listOf extraJavacArgs Multi eisop
LocalWords: Werror Astubs testCompileJava excludeTests camelCase classfiles
LocalWords: Werror Astubs testCompileJava excludeTests camelCase
LocalWords: withType configureEach compileMainGeneratedDataTemplateJava
LocalWords: compileMainGeneratedRestJava subprojects allprojects mavenLocal
LocalWords: delombok addLombokGeneratedAnnotation addSuppressWarnings cfLocal
Expand Down
4 changes: 2 additions & 2 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ ktlint = "1.8.0"
[libraries]
truth = "com.google.truth:truth:1.4.5"

# Versions used in build script, libraries added here for Dependabot
junitJupiter-api = { module = "org.junit.jupiter:junit-jupiter-api", version.ref="junitJupiter" }
# Versions used in the build script; the libraries are listed here so that Dependabot updates them.
junitJupiter-api = { module = "org.junit.jupiter:junit-jupiter-api", version.ref = "junitJupiter" }
ktlint = { module = "com.pinterest.ktlint:ktlint-cli", version.ref = "ktlint" }

[plugins]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class CFGroovyPluginFunctionalTest : GroovyPluginFunctionalTest() {
}
repositories {
mavenCentral()
}
}

"""
.trimIndent()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class CfPluginFunctionalTest : KotlinPluginFunctionalTest() {
}
repositories {
mavenCentral()
}
}

"""
.trimIndent()
Expand Down Expand Up @@ -435,9 +435,9 @@ class CfPluginFunctionalTest : KotlinPluginFunctionalTest() {

@Test
fun `test checkerFramework configuration`() {
// This tests that the version of the Checker Framework in the checker framework configuration
// is used instead of the version in 'version'. Both versions are pinned rather than tracking
// TEST_CF_VERSION: 'version' supplies checker-qual, and a checker-qual older than checker.jar
// This tests that the version of the Checker Framework in the `checkerFramework` configuration
// is used instead of the version in `version`. Both versions are pinned rather than tracking
// TEST_CF_VERSION: `version` supplies checker-qual, and a checker-qual older than checker.jar
// may lack qualifiers that checker.jar refers to, which fails for a reason unrelated to which
// version this test expects to win.
val configurationVersion = "3.53.0"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ fun File.writeLombokExample() {
}
}

/** Writes a class that uses lombok and that the Nullness Checker issues no warning about. */
/** Writes a class that uses Lombok and that the Nullness Checker issues no warning about. */
fun File.writeCorrectLombokExample() {
File(this.resolve("src/main/java/lib").apply { mkdirs() }, "Correct.java").apply {
createNewFile()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,26 +12,26 @@ class OtherPluginsFunctionalTest : KotlinPluginFunctionalTest() {
"""
repositories {
mavenCentral()
}
}
"""
.trimIndent()
)
}

@Test
fun `test lombok 8 12 1`() {
// Lombok 8.12.1 does not support Java 25 and later.
// Version 8.12.1 of the Lombok plugin does not support Java 25 and later.
if (testJavaVersion >= 25) {
return
}
buildFile.appendText(
"""
plugins {
plugins {
`java-library`
id("org.checkerframework")
id("io.freefair.lombok").version("8.12.1")
}

configure<CheckerFrameworkExtension> {
version = "$TEST_CF_VERSION"
checkers = listOf("org.checkerframework.checker.nullness.NullnessChecker")
Expand Down Expand Up @@ -59,12 +59,12 @@ class OtherPluginsFunctionalTest : KotlinPluginFunctionalTest() {
fun `test lombok latest`() {
buildFile.appendText(
"""
plugins {
plugins {
`java-library`
id("org.checkerframework")
id("io.freefair.lombok").version("9.5.0")
}

configure<CheckerFrameworkExtension> {
version = "$TEST_CF_VERSION"
checkers = listOf("org.checkerframework.checker.nullness.NullnessChecker")
Expand Down Expand Up @@ -92,7 +92,7 @@ class OtherPluginsFunctionalTest : KotlinPluginFunctionalTest() {
fun `test forking is visible at configuration time with lombok`() {
buildFile.appendText(
"""
plugins {
plugins {
`java-library`
id("org.checkerframework")
id("io.freefair.lombok").version("9.5.0")
Expand Down Expand Up @@ -121,15 +121,15 @@ class OtherPluginsFunctionalTest : KotlinPluginFunctionalTest() {
}

@Test
fun `test disabling CF with lombok `() {
fun `test disabling CF with lombok`() {
buildFile.appendText(
"""
plugins {
plugins {
`java-library`
id("org.checkerframework")
id("io.freefair.lombok").version("9.5.0")
}

configure<CheckerFrameworkExtension> {
version = "$TEST_CF_VERSION"
checkers = listOf("org.checkerframework.checker.nullness.NullnessChecker")
Expand Down Expand Up @@ -158,7 +158,7 @@ class OtherPluginsFunctionalTest : KotlinPluginFunctionalTest() {
fun `test disabling CF for compileJava only, with lombok`() {
buildFile.appendText(
"""
plugins {
plugins {
`java-library`
id("org.checkerframework")
id("io.freefair.lombok").version("9.5.0")
Expand Down Expand Up @@ -202,7 +202,7 @@ class OtherPluginsFunctionalTest : KotlinPluginFunctionalTest() {
fun `test disabling CF for the delombok task only`() {
buildFile.appendText(
"""
plugins {
plugins {
`java-library`
id("org.checkerframework")
id("io.freefair.lombok").version("9.5.0")
Expand Down
Loading
Loading