Why
Maven users have no way to run open-java-format from their build today.
Proposal
A plugin dev.openjavaformat:open-java-format-maven-plugin, released together with the formatter and under the same version, with two goals modelled on spotify/fmt-maven-plugin:
| Goal |
Default phase |
What it does |
format |
process-sources |
Formats the Java files in place |
check |
verify |
Fails the build and lists the files that are not formatted |
<plugin>
<groupId>dev.openjavaformat</groupId>
<artifactId>open-java-format-maven-plugin</artifactId>
<version><!-- the formatter version --></version>
<executions>
<execution>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
From the command line the prefix gives mvn open-java-format:format and mvn open-java-format:check.
As few settings as possible, in line with a formatter that has none: the source roots, which default to the module's compile and test source roots, includes and excludes, and skip. The style is always OJF.
How the formatter runs
The formatter needs javac's internal packages exported. Running it inside the Maven JVM would make every project add the five --add-exports flags to .mvn/jvm.config, which is what Cosium/git-code-format-maven-plugin asks its users to do. Two ways avoid that:
- Fork one JVM per module. Start the current JDK with the flags and the formatter's classpath, and hand all files of the module to
com.palantir.javaformat.java.Main in a single call through an @argfile: --replace for format, --dry-run --set-exit-if-changed for check. BootstrappingFormatterService in open-java-format-jdk-bootstrap already builds this command line, although it starts one process per file. spotify/fmt-maven-plugin forks by default for the same reason, see its forkMode.
- The native binary from
open-java-format-native, as the Gradle plugin does with openjavaformat.native.formatter, on Linux with glibc and on macOS.
The formatter comes from the plugin's own dependencies, so it needs nothing from the project's repositories. That is the principle of #20 for the Gradle plugin.
Building it here
The repository builds with Gradle, and a Maven plugin needs a plugin descriptor. org.gradlex.maven-plugin-development generates it from the mojo annotations; the alternative is a small Maven build for this one module. Publishing goes through the existing JReleaser conventions together with the other jars.
Done when
- the plugin is on Maven Central under the formatter's version;
- an integration test runs real
mvn on a sample multi-module project against the locally published plugin, for both goals, on Java 21 and without .mvn/jvm.config;
- the output of
format is byte-identical to the command line with --ojf;
- the website gets a Maven page under Get started, and the Maven parts of the Spotless and Migrate pages point to it.
Related
Why
Maven users have no way to run open-java-format from their build today.
palantirJavaFormatstep hardcodescom.palantir.javaformat:palantir-java-format, and Add new action for open-java-format diffplug/spotless#3084, which adds anopenJavaFormatstep, was closed. The details are at https://openjavaformat.dev/get-started/spotless/.Proposal
A plugin
dev.openjavaformat:open-java-format-maven-plugin, released together with the formatter and under the same version, with two goals modelled on spotify/fmt-maven-plugin:formatprocess-sourcescheckverifyFrom the command line the prefix gives
mvn open-java-format:formatandmvn open-java-format:check.As few settings as possible, in line with a formatter that has none: the source roots, which default to the module's compile and test source roots, includes and excludes, and
skip. The style is always OJF.How the formatter runs
The formatter needs javac's internal packages exported. Running it inside the Maven JVM would make every project add the five
--add-exportsflags to.mvn/jvm.config, which is what Cosium/git-code-format-maven-plugin asks its users to do. Two ways avoid that:com.palantir.javaformat.java.Mainin a single call through an@argfile:--replaceforformat,--dry-run --set-exit-if-changedforcheck.BootstrappingFormatterServiceinopen-java-format-jdk-bootstrapalready builds this command line, although it starts one process per file. spotify/fmt-maven-plugin forks by default for the same reason, see itsforkMode.open-java-format-native, as the Gradle plugin does withopenjavaformat.native.formatter, on Linux with glibc and on macOS.The formatter comes from the plugin's own dependencies, so it needs nothing from the project's repositories. That is the principle of #20 for the Gradle plugin.
Building it here
The repository builds with Gradle, and a Maven plugin needs a plugin descriptor.
org.gradlex.maven-plugin-developmentgenerates it from the mojo annotations; the alternative is a small Maven build for this one module. Publishing goes through the existing JReleaser conventions together with the other jars.Done when
mvnon a sample multi-module project against the locally published plugin, for both goals, on Java 21 and without.mvn/jvm.config;formatis byte-identical to the command line with--ojf;Related
CodeFormatterFactory, so an open-java-format formatter for it would be a smaller, complementary step.