Skip to content

Add maxLineLength option to googleJavaFormat step (requires gjf 1.37.0+) - #3152

Open
xzxiaoshan wants to merge 1 commit into
diffplug:mainfrom
xzxiaoshan:feat/google-java-format-max-line-length
Open

xzxiaoshan wants to merge 1 commit into
diffplug:mainfrom
xzxiaoshan:feat/google-java-format-max-line-length

Conversation

@xzxiaoshan

Copy link
Copy Markdown

Fixes #3151

Summary

Exposes the column-limit setting that google-java-format v1.37.0 added via JavaFormatterOptions.Style.builder().maxLineLength(int) (google/google-java-format#425, open since Dec 2019 — this was previously impossible because the limit was a compile-time-inlined constant, which is why #1563 was closed back in 2023).

Gradle

googleJavaFormat('1.37.0').maxLineLength(120)

Maven

<googleJavaFormat>
    <version>1.37.0</version>
    <maxLineLength>120</maxLineLength>
</googleJavaFormat>

Setting maxLineLength together with a gjf version older than 1.37.0 fails at configuration time with a clear message (maxLineLength requires google-java-format 1.37.0 or later (you are using 1.36.1)).

Compatibility fix included

Upstream 1.37.0 turned JavaFormatterOptions.Style from an enum into a record, which removed Style.valueOf(String) — so the existing glue code would crash with NoSuchMethodError as soon as a user pins gjf 1.37.0 (and would also break #3130, the default-version bump, if merged as-is). This PR resolves style names against the GOOGLE/AOSP constants, which exist as static fields in both the enum and the record, so the step works on all supported gjf versions again. There is a new regression test (behavior137) covering gjf 1.37.0 with default settings.

Implementation notes

  • The glue code still compiles against the pinned gjf 1.28.0 (needed for the JDK-17 tier, and 1.37.0 is class-file v65 which JDK 17 can't even read), so the 1.37.0 builder is invoked reflectively, only when maxLineLength is set.
  • Reflection methods are looked up on the public JavaFormatterOptions$Style$Builder type rather than the builder's runtime class — gjf 1.37.0 implements the builder via AutoBuilder, and the generated class is package-private, which makes builder.getClass().getMethod(...).invoke(...) throw IllegalAccessException.
  • maxLineLength is part of the step's equality state, so Gradle/Maven correctly re-run when it changes.

Testing

  • GoogleJavaFormatStepTest: new behaviorWithMaxLineLength, behavior137 (gjf 1.37.0 with defaults), and maxLineLengthRequiresVersion1Dot37OrLater (config-time error) — all pass on JDK 21
  • All existing GoogleJavaFormatStepTest cases still pass (no behavior change when maxLineLength is unset)
  • GoogleJavaFormatIntegrationTest.integrationWithMaxLineLength passes (Gradle plugin, spotlessApply + up-to-date checks)
  • Maven plugin verified end-to-end by hand with the locally published 3.10.5-SNAPSHOT plugin (mvn apply output matches byte-for-byte, including line endings; the old-version error message renders correctly). The in-repo GoogleJavaFormatTest.specificVersionMaxLineLength is included for CI (gated on JVM 21+), but couldn't run on my Windows machine because of a pre-existing harness issue there (cmd /c mvnw fails to resolve mvnw.cmd when an extension-less mvnw exists — unrelated to this change; it reproduces on a clean checkout too).
  • spotlessCheck and spotbugsMain/spotbugsGoogleJavaFormat pass
  • Full CI matrix (JDK 17/21/25/26)

Expose the column-limit setting that google-java-format 1.37.0 added via
JavaFormatterOptions.Style.builder().maxLineLength(int):

- Gradle: googleJavaFormat('1.37.0').maxLineLength(240)
- Maven:  <googleJavaFormat><version>1.37.0</version><maxLineLength>240</maxLineLength></googleJavaFormat>

The step rejects maxLineLength with gjf older than 1.37.0 at
configuration time with a clear error message. The glue code keeps
compiling against gjf 1.28.0 (so older versions and JDK 17 keep
working) and calls the 1.37.0 builder API reflectively.

google-java-format 1.37.0 turned JavaFormatterOptions.Style from an
enum into a record, which removed Style.valueOf(String) and broke the
existing glue with a NoSuchMethodError. Style names are now resolved
against the GOOGLE/AOSP constants, which exist as static fields in
both shapes, so the step works again on 1.37.0+ regardless of
maxLineLength.

Fixes diffplug#3151
@xzxiaoshan

Copy link
Copy Markdown
Author

On the surface this is a fairly ordinary property addition, but it fulfills something the community has been hoping for over the long term — the underlying upstream request (google/google-java-format#425) stayed open for nearly seven years, and the earlier equivalent request here (#1563) was closed back in 2023 as impossible to implement until upstream made the limit configurable. So finally being able to expose it through Spotless is genuinely meaningful for the many developers who'd like a column limit other than 100. If this PR looks good and can be merged, it would be great to see it included in a release relatively soon so users can start taking advantage of it. Thank you very much for maintaining Spotless and for taking the time to review this contribution!
@nedtwigg @Goooler

@jawadshaikst jawadshaikst left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1, would love to get this merged and released.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Expose maxLineLength on the googleJavaFormat step (configurable upstream since gjf 1.37.0)

2 participants