What happens
In a build that only applies dev.openjavaformat.java-format, ./gradlew formatDiff fails with a raw JVM error:
Execution failed for task ':formatDiff' (registered by plugin 'dev.openjavaformat.java-format').
> class com.palantir.javaformat.java.JavaInput (in unnamed module @0x…) cannot access class
com.sun.tools.javac.parser.Tokens$TokenKind (in module jdk.compiler) because module jdk.compiler
does not export com.sun.tools.javac.parser to unnamed module @0x…
Nothing in it tells the user what to change.
Why
The Java-based formatter runs inside the Gradle daemon, and a plain daemon JVM does not export javac's internal packages. FormatDiff.format catches IOException and FormatterException only, so the IllegalAccessError goes straight up to Gradle.
Both known fixes work. Checked with plugin 2.98.0.1, Gradle 9.7.1 and Temurin 21:
openjavaformat.native.formatter=true in gradle.properties, on Linux with glibc and on macOS;
- the five
--add-exports jdk.compiler/com.sun.tools.javac.{api,file,parser,tree,util}=ALL-UNNAMED flags in org.gradle.jvmargs, as this repository's own gradle.properties has them.
Proposal
Make formatDiff fail with a message that names both settings and links to https://openjavaformat.dev/get-started/gradle/.
Two ways to get there:
- catch
IllegalAccessError around formatter.getFormatReplacements(...) and rethrow it as a GradleException with that message, or
- check up front whether
jdk.compiler exports com.sun.tools.javac.parser to the formatter's class loader, and fail before the first file. This also avoids printing Formatting <file> for a run that cannot succeed.
The native path is not affected and needs no change.
Reproduce
// build.gradle
plugins {
id 'java'
id 'dev.openjavaformat.java-format' version '2.98.0.1'
}
repositories {
mavenCentral()
}
Commit a Java file, edit it, and run ./gradlew formatDiff with no gradle.properties.
Done when
- the failure names both settings and the page above;
- it is checked in a real consumer build against a published or locally published plugin, not only with TestKit.
What happens
In a build that only applies
dev.openjavaformat.java-format,./gradlew formatDifffails with a raw JVM error:Nothing in it tells the user what to change.
Why
The Java-based formatter runs inside the Gradle daemon, and a plain daemon JVM does not export javac's internal packages.
FormatDiff.formatcatchesIOExceptionandFormatterExceptiononly, so theIllegalAccessErrorgoes straight up to Gradle.Both known fixes work. Checked with plugin 2.98.0.1, Gradle 9.7.1 and Temurin 21:
openjavaformat.native.formatter=trueingradle.properties, on Linux with glibc and on macOS;--add-exports jdk.compiler/com.sun.tools.javac.{api,file,parser,tree,util}=ALL-UNNAMEDflags inorg.gradle.jvmargs, as this repository's owngradle.propertieshas them.Proposal
Make
formatDifffail with a message that names both settings and links to https://openjavaformat.dev/get-started/gradle/.Two ways to get there:
IllegalAccessErroraroundformatter.getFormatReplacements(...)and rethrow it as aGradleExceptionwith that message, orjdk.compilerexportscom.sun.tools.javac.parserto the formatter's class loader, and fail before the first file. This also avoids printingFormatting <file>for a run that cannot succeed.The native path is not affected and needs no change.
Reproduce
Commit a Java file, edit it, and run
./gradlew formatDiffwith nogradle.properties.Done when