From 8b24b220ffc5722c60fa9956f6023d92d30bd856 Mon Sep 17 00:00:00 2001
From: Simon Gamma <github@survive.ch>
Date: Tue, 28 Feb 2023 20:55:40 +0100
Subject: [PATCH 01/15] use compile-only sourceset for gjf

---
 lib/build.gradle                              |  16 +-
 .../java/GoogleJavaFormatFormatterFunc.java   |  71 +++++++++
 ...rmatRemoveUnusedImporterFormatterFunc.java |  43 ++++++
 .../glue/java/GoogleJavaFormatUtils.java      |  54 +++++++
 .../spotless/java/GoogleJavaFormatStep.java   | 144 ++----------------
 .../glue/java/GoogleJavaFormatUtilsTest.java  |  63 ++++++++
 .../java/GoogleJavaFormatStepTest.java        |  40 -----
 7 files changed, 258 insertions(+), 173 deletions(-)
 create mode 100644 lib/src/googleJavaFormat/java/com/diffplug/spotless/glue/java/GoogleJavaFormatFormatterFunc.java
 create mode 100644 lib/src/googleJavaFormat/java/com/diffplug/spotless/glue/java/GoogleJavaFormatRemoveUnusedImporterFormatterFunc.java
 create mode 100644 lib/src/googleJavaFormat/java/com/diffplug/spotless/glue/java/GoogleJavaFormatUtils.java
 create mode 100644 lib/src/testGoogleJavaFormat/java/com/diffplug/spotless/glue/java/GoogleJavaFormatUtilsTest.java

diff --git a/lib/build.gradle b/lib/build.gradle
index 9a6e7913d5..e939f7249e 100644
--- a/lib/build.gradle
+++ b/lib/build.gradle
@@ -10,6 +10,7 @@ apply from: rootProject.file('gradle/java-publish.gradle')
 def NEEDS_GLUE = [
 	'sortPom',
 	'palantirJavaFormat',
+	'googleJavaFormat',
 	'ktfmt',
 	'ktlint',
 	'flexmark',
@@ -20,11 +21,21 @@ def NEEDS_GLUE = [
 	'cleanthat'
 ]
 for (glue in NEEDS_GLUE) {
-	sourceSets.register(glue) {
+	// main glue
+	def mainGlue = sourceSets.register(glue) {
 		compileClasspath += sourceSets.main.output
 		runtimeClasspath += sourceSets.main.output
 		java {}
 	}
+	// test glue
+	sourceSets.register("test${glue.capitalize()}") {
+		compileClasspath += mainGlue.get().compileClasspath + mainGlue.get().output + sourceSets.test.output
+		runtimeClasspath += mainGlue.get().compileClasspath + mainGlue.get().output + sourceSets.test.output
+		java {}
+	}
+	configurations.named("test${glue.capitalize()}Implementation").configure {
+		extendsFrom(configurations.named("testImplementation").get())
+	}
 }
 
 versionCompatibility {
@@ -70,6 +81,9 @@ dependencies {
 
 	palantirJavaFormatCompileOnly 'com.palantir.javaformat:palantir-java-format:1.1.0' 	// this version needs to stay compilable against Java 8 for CI Job testNpm
 
+	googleJavaFormatCompileOnly 'com.google.googlejavaformat:google-java-format:1.8' // minimum required version for jdk 11
+	testGoogleJavaFormatImplementation "com.diffplug.durian:durian-core:$VER_DURIAN"
+
 	// used jackson-based formatters
 	jacksonCompileOnly 'com.fasterxml.jackson.core:jackson-databind:2.14.2'
 	jacksonCompileOnly 'com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.14.2'
diff --git a/lib/src/googleJavaFormat/java/com/diffplug/spotless/glue/java/GoogleJavaFormatFormatterFunc.java b/lib/src/googleJavaFormat/java/com/diffplug/spotless/glue/java/GoogleJavaFormatFormatterFunc.java
new file mode 100644
index 0000000000..a326cf1f69
--- /dev/null
+++ b/lib/src/googleJavaFormat/java/com/diffplug/spotless/glue/java/GoogleJavaFormatFormatterFunc.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2023 DiffPlug
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.diffplug.spotless.glue.java;
+
+import static com.diffplug.spotless.glue.java.GoogleJavaFormatUtils.fixWindowsBug;
+
+import java.util.Objects;
+
+import javax.annotation.Nonnull;
+
+import com.google.googlejavaformat.java.Formatter;
+import com.google.googlejavaformat.java.FormatterException;
+import com.google.googlejavaformat.java.ImportOrderer;
+import com.google.googlejavaformat.java.JavaFormatterOptions;
+import com.google.googlejavaformat.java.RemoveUnusedImports;
+import com.google.googlejavaformat.java.StringWrapper;
+
+import com.diffplug.spotless.FormatterFunc;
+
+public class GoogleJavaFormatFormatterFunc implements FormatterFunc {
+
+	@Nonnull
+	private final Formatter formatter;
+
+	@Nonnull
+	private final String version;
+	@Nonnull
+	private final JavaFormatterOptions.Style formatterStyle;
+	private final boolean reflowStrings;
+
+	public GoogleJavaFormatFormatterFunc(@Nonnull String version, @Nonnull String style, boolean reflowStrings) {
+		this.version = Objects.requireNonNull(version);
+		this.formatterStyle = JavaFormatterOptions.Style.valueOf(Objects.requireNonNull(style));
+		this.reflowStrings = reflowStrings;
+
+		this.formatter = new Formatter(JavaFormatterOptions.builder()
+				.style(formatterStyle)
+				.build());
+	}
+
+	@Override
+	@Nonnull
+	public String apply(@Nonnull String input) throws Exception {
+		String formatted = formatter.formatSource(input);
+		String removedUnused = RemoveUnusedImports.removeUnusedImports(formatted);
+		String sortedImports = ImportOrderer.reorderImports(removedUnused, formatterStyle);
+		String reflowedLongStrings = reflowLongStrings(sortedImports);
+		return fixWindowsBug(reflowedLongStrings, version);
+	}
+
+	private String reflowLongStrings(String input) throws FormatterException {
+		if (reflowStrings) {
+			return StringWrapper.wrap(input, formatter);
+		} else {
+			return input;
+		}
+	}
+}
diff --git a/lib/src/googleJavaFormat/java/com/diffplug/spotless/glue/java/GoogleJavaFormatRemoveUnusedImporterFormatterFunc.java b/lib/src/googleJavaFormat/java/com/diffplug/spotless/glue/java/GoogleJavaFormatRemoveUnusedImporterFormatterFunc.java
new file mode 100644
index 0000000000..0073ce9dc9
--- /dev/null
+++ b/lib/src/googleJavaFormat/java/com/diffplug/spotless/glue/java/GoogleJavaFormatRemoveUnusedImporterFormatterFunc.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2023 DiffPlug
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.diffplug.spotless.glue.java;
+
+import static com.diffplug.spotless.glue.java.GoogleJavaFormatUtils.fixWindowsBug;
+
+import java.util.Objects;
+
+import javax.annotation.Nonnull;
+
+import com.google.googlejavaformat.java.RemoveUnusedImports;
+
+import com.diffplug.spotless.FormatterFunc;
+
+public class GoogleJavaFormatRemoveUnusedImporterFormatterFunc implements FormatterFunc {
+
+	@Nonnull
+	private final String version;
+
+	public GoogleJavaFormatRemoveUnusedImporterFormatterFunc(@Nonnull String version) {
+		this.version = Objects.requireNonNull(version);
+	}
+
+	@Override
+	@Nonnull
+	public String apply(@Nonnull String input) throws Exception {
+		String removedUnused = RemoveUnusedImports.removeUnusedImports(input);
+		return fixWindowsBug(removedUnused, version);
+	}
+}
diff --git a/lib/src/googleJavaFormat/java/com/diffplug/spotless/glue/java/GoogleJavaFormatUtils.java b/lib/src/googleJavaFormat/java/com/diffplug/spotless/glue/java/GoogleJavaFormatUtils.java
new file mode 100644
index 0000000000..98f47a6097
--- /dev/null
+++ b/lib/src/googleJavaFormat/java/com/diffplug/spotless/glue/java/GoogleJavaFormatUtils.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2023 DiffPlug
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.diffplug.spotless.glue.java;
+
+import com.diffplug.spotless.LineEnding;
+
+public class GoogleJavaFormatUtils {
+
+	private static final boolean IS_WINDOWS = LineEnding.PLATFORM_NATIVE.str().equals("\r\n");
+
+	/**
+	 * google-java-format-1.1's removeUnusedImports does *wacky* stuff on Windows.
+	 * The beauty of normalizing all line endings to unix!
+	 */
+	static String fixWindowsBug(String input, String version) {
+		if (IS_WINDOWS && version.equals("1.1")) {
+			int firstImport = input.indexOf("\nimport ");
+			if (firstImport == 0) {
+				return input;
+			} else if (firstImport > 0) {
+				int numToTrim = 0;
+				char prevChar;
+				do {
+					++numToTrim;
+					prevChar = input.charAt(firstImport - numToTrim);
+				} while (Character.isWhitespace(prevChar) && (firstImport - numToTrim) > 0);
+				if (firstImport - numToTrim == 0) {
+					// import was the very first line, and we'd like to maintain a one-line gap
+					++numToTrim;
+				} else if (prevChar == ';' || prevChar == '/') {
+					// import came after either license or a package declaration
+					--numToTrim;
+				}
+				if (numToTrim > 0) {
+					return input.substring(0, firstImport - numToTrim + 2) + input.substring(firstImport + 1);
+				}
+			}
+		}
+		return input;
+	}
+}
diff --git a/lib/src/main/java/com/diffplug/spotless/java/GoogleJavaFormatStep.java b/lib/src/main/java/com/diffplug/spotless/java/GoogleJavaFormatStep.java
index 6390c619a9..9a3b49c095 100644
--- a/lib/src/main/java/com/diffplug/spotless/java/GoogleJavaFormatStep.java
+++ b/lib/src/main/java/com/diffplug/spotless/java/GoogleJavaFormatStep.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016-2022 DiffPlug
+ * Copyright 2016-2023 DiffPlug
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,17 +16,14 @@
 package com.diffplug.spotless.java;
 
 import java.io.Serializable;
-import java.lang.reflect.Method;
+import java.lang.reflect.Constructor;
 import java.util.Objects;
 
 import com.diffplug.spotless.FormatterFunc;
 import com.diffplug.spotless.FormatterStep;
 import com.diffplug.spotless.JarState;
 import com.diffplug.spotless.Jvm;
-import com.diffplug.spotless.LineEnding;
 import com.diffplug.spotless.Provisioner;
-import com.diffplug.spotless.ThrowingEx.BiFunction;
-import com.diffplug.spotless.ThrowingEx.Function;
 
 /** Wraps up <a href="https://github.com/google/google-java-format">google-java-format</a> as a FormatterStep. */
 public class GoogleJavaFormatStep {
@@ -37,27 +34,6 @@ private GoogleJavaFormatStep() {}
 	private static final boolean DEFAULT_REFLOW_LONG_STRINGS = false;
 	static final String NAME = "google-java-format";
 	static final String MAVEN_COORDINATE = "com.google.googlejavaformat:google-java-format";
-	static final String FORMATTER_CLASS = "com.google.googlejavaformat.java.Formatter";
-	static final String FORMATTER_METHOD = "formatSource";
-
-	private static final String OPTIONS_CLASS = "com.google.googlejavaformat.java.JavaFormatterOptions";
-	private static final String OPTIONS_BUILDER_METHOD = "builder";
-	private static final String OPTIONS_BUILDER_CLASS = "com.google.googlejavaformat.java.JavaFormatterOptions$Builder";
-	private static final String OPTIONS_BUILDER_STYLE_METHOD = "style";
-	private static final String OPTIONS_BUILDER_BUILD_METHOD = "build";
-	private static final String OPTIONS_Style = "com.google.googlejavaformat.java.JavaFormatterOptions$Style";
-
-	private static final String REMOVE_UNUSED_CLASS = "com.google.googlejavaformat.java.RemoveUnusedImports";
-	private static final String REMOVE_UNUSED_METHOD = "removeUnusedImports";
-
-	private static final String REMOVE_UNUSED_IMPORT_JavadocOnlyImports = "com.google.googlejavaformat.java.RemoveUnusedImports$JavadocOnlyImports";
-	private static final String REMOVE_UNUSED_IMPORT_JavadocOnlyImports_Keep = "KEEP";
-
-	private static final String IMPORT_ORDERER_CLASS = "com.google.googlejavaformat.java.ImportOrderer";
-	private static final String IMPORT_ORDERER_METHOD = "reorderImports";
-
-	private static final String STRING_WRAPPER_CLASS = "com.google.googlejavaformat.java.StringWrapper";
-	private static final String STRING_WRAPPER_METHOD = "wrap";
 
 	/** Creates a step which formats everything - code, import order, and unused imports. */
 	public static FormatterStep create(Provisioner provisioner) {
@@ -93,7 +69,7 @@ public static FormatterStep create(String groupArtifact, String version, String
 				State::createFormat);
 	}
 
-	static final Jvm.Support<String> JVM_SUPPORT = Jvm.<String> support(NAME).add(8, "1.7").add(11, "1.15.0");
+	static final Jvm.Support<String> JVM_SUPPORT = Jvm.<String> support(NAME).add(11, "1.15.0");
 
 	public static String defaultGroupArtifact() {
 		return MAVEN_COORDINATE;
@@ -144,120 +120,24 @@ static final class State implements Serializable {
 			this.reflowLongStrings = reflowLongStrings;
 		}
 
-		@SuppressWarnings({"unchecked", "rawtypes"})
 		FormatterFunc createFormat() throws Exception {
-			ClassLoader classLoader = jarState.getClassLoader();
-
-			// instantiate the formatter and get its format method
-			Class<?> optionsClass = classLoader.loadClass(OPTIONS_CLASS);
-			Class<?> optionsBuilderClass = classLoader.loadClass(OPTIONS_BUILDER_CLASS);
-			Method optionsBuilderMethod = optionsClass.getMethod(OPTIONS_BUILDER_METHOD);
-			Object optionsBuilder = optionsBuilderMethod.invoke(null);
-
-			Class<?> optionsStyleClass = classLoader.loadClass(OPTIONS_Style);
-			Object styleConstant = Enum.valueOf((Class<Enum>) optionsStyleClass, style);
-			Method optionsBuilderStyleMethod = optionsBuilderClass.getMethod(OPTIONS_BUILDER_STYLE_METHOD, optionsStyleClass);
-			optionsBuilderStyleMethod.invoke(optionsBuilder, styleConstant);
-
-			Method optionsBuilderBuildMethod = optionsBuilderClass.getMethod(OPTIONS_BUILDER_BUILD_METHOD);
-			Object options = optionsBuilderBuildMethod.invoke(optionsBuilder);
-
-			Class<?> formatterClazz = classLoader.loadClass(FORMATTER_CLASS);
-			Object formatter = formatterClazz.getConstructor(optionsClass).newInstance(options);
-			Method formatterMethod = formatterClazz.getMethod(FORMATTER_METHOD, String.class);
+			final ClassLoader classLoader = jarState.getClassLoader();
+			Class<?> formatterFunc = classLoader.loadClass("com.diffplug.spotless.glue.java.GoogleJavaFormatFormatterFunc");
+			Constructor<?> constructor = formatterFunc.getConstructor(String.class, String.class, boolean.class);
+			FormatterFunc googleJavaFormatFormatterFunc = (FormatterFunc) constructor.newInstance(version, style, reflowLongStrings);
 
-			Function<String, String> removeUnused = constructRemoveUnusedFunction(classLoader);
-
-			Class<?> importOrdererClass = classLoader.loadClass(IMPORT_ORDERER_CLASS);
-			Method importOrdererMethod = importOrdererClass.getMethod(IMPORT_ORDERER_METHOD, String.class);
-
-			BiFunction<String, Object, String> reflowLongStrings = this.reflowLongStrings ? constructReflowLongStringsFunction(classLoader, formatterClazz) : (s, f) -> s;
-
-			return JVM_SUPPORT.suggestLaterVersionOnError(version, (input -> {
-				String formatted = (String) formatterMethod.invoke(formatter, input);
-				String removedUnused = removeUnused.apply(formatted);
-				String sortedImports = (String) importOrdererMethod.invoke(null, removedUnused);
-				String reflowedLongStrings = reflowLongStrings.apply(sortedImports, formatter);
-				return fixWindowsBug(reflowedLongStrings, version);
-			}));
+			return JVM_SUPPORT.suggestLaterVersionOnError(version, googleJavaFormatFormatterFunc);
 		}
 
 		FormatterFunc createRemoveUnusedImportsOnly() throws Exception {
 			ClassLoader classLoader = jarState.getClassLoader();
-			Function<String, String> removeUnused = constructRemoveUnusedFunction(classLoader);
-			return JVM_SUPPORT.suggestLaterVersionOnError(version, (input -> fixWindowsBug(removeUnused.apply(input), version)));
-		}
-
-		private static Function<String, String> constructRemoveUnusedFunction(ClassLoader classLoader)
-				throws NoSuchMethodException, ClassNotFoundException {
-			Class<?> removeUnusedClass = classLoader.loadClass(REMOVE_UNUSED_CLASS);
-			Class<?> removeJavadocOnlyClass;
-			try {
-				// google-java-format 1.7 or lower
-				removeJavadocOnlyClass = classLoader.loadClass(REMOVE_UNUSED_IMPORT_JavadocOnlyImports);
-			} catch (ClassNotFoundException e) {
-				// google-java-format 1.8+
-				removeJavadocOnlyClass = null;
-			}
+			Class<?> formatterFunc = classLoader.loadClass("com.diffplug.spotless.glue.java.GoogleJavaFormatRemoveUnusedImporterFormatterFunc");
+			Constructor<?> constructor = formatterFunc.getConstructor(String.class); //version
+			FormatterFunc googleJavaFormatRemoveUnusedImporterFormatterFunc = (FormatterFunc) constructor.newInstance(version);
 
-			Function<String, String> removeUnused;
-			if (removeJavadocOnlyClass != null) {
-				@SuppressWarnings({"unchecked", "rawtypes"})
-				Object removeJavadocConstant = Enum.valueOf((Class<Enum>) removeJavadocOnlyClass, REMOVE_UNUSED_IMPORT_JavadocOnlyImports_Keep);
-				Method removeUnusedMethod = removeUnusedClass.getMethod(REMOVE_UNUSED_METHOD, String.class, removeJavadocOnlyClass);
-				removeUnused = (x) -> (String) removeUnusedMethod.invoke(null, x, removeJavadocConstant);
-			} else {
-				Method removeUnusedMethod = removeUnusedClass.getMethod(REMOVE_UNUSED_METHOD, String.class);
-				removeUnused = (x) -> (String) removeUnusedMethod.invoke(null, x);
-			}
-			return removeUnused;
+			return JVM_SUPPORT.suggestLaterVersionOnError(version, googleJavaFormatRemoveUnusedImporterFormatterFunc);
 		}
 
-		private static BiFunction<String, Object, String> constructReflowLongStringsFunction(ClassLoader classLoader, Class<?> formatterClazz) throws NoSuchMethodException {
-			Class<?> stringWrapperClass;
-			try {
-				stringWrapperClass = classLoader.loadClass(STRING_WRAPPER_CLASS);
-			} catch (ClassNotFoundException e) {
-				// google-java-format 1.7 or lower, which happen to be LATEST_VERSION_JRE_8, so rely on suggestJre11 for the error
-				return (s, f) -> {
-					throw e;
-				};
-			}
-			Method stringWrapperMethod = stringWrapperClass.getMethod(STRING_WRAPPER_METHOD, String.class, formatterClazz);
-			return (s, f) -> (String) stringWrapperMethod.invoke(null, s, f);
-		}
 	}
 
-	private static final boolean IS_WINDOWS = LineEnding.PLATFORM_NATIVE.str().equals("\r\n");
-
-	/**
-	 * google-java-format-1.1's removeUnusedImports does *wacky* stuff on Windows.
-	 * The beauty of normalizing all line endings to unix!
-	 */
-	static String fixWindowsBug(String input, String version) {
-		if (IS_WINDOWS && version.equals("1.1")) {
-			int firstImport = input.indexOf("\nimport ");
-			if (firstImport == 0) {
-				return input;
-			} else if (firstImport > 0) {
-				int numToTrim = 0;
-				char prevChar;
-				do {
-					++numToTrim;
-					prevChar = input.charAt(firstImport - numToTrim);
-				} while (Character.isWhitespace(prevChar) && (firstImport - numToTrim) > 0);
-				if (firstImport - numToTrim == 0) {
-					// import was the very first line, and we'd like to maintain a one-line gap
-					++numToTrim;
-				} else if (prevChar == ';' || prevChar == '/') {
-					// import came after either license or a package declaration
-					--numToTrim;
-				}
-				if (numToTrim > 0) {
-					return input.substring(0, firstImport - numToTrim + 2) + input.substring(firstImport + 1);
-				}
-			}
-		}
-		return input;
-	}
 }
diff --git a/lib/src/testGoogleJavaFormat/java/com/diffplug/spotless/glue/java/GoogleJavaFormatUtilsTest.java b/lib/src/testGoogleJavaFormat/java/com/diffplug/spotless/glue/java/GoogleJavaFormatUtilsTest.java
new file mode 100644
index 0000000000..a6403c18a0
--- /dev/null
+++ b/lib/src/testGoogleJavaFormat/java/com/diffplug/spotless/glue/java/GoogleJavaFormatUtilsTest.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2023 DiffPlug
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.diffplug.spotless.glue.java;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import com.diffplug.common.base.StringPrinter;
+
+public class GoogleJavaFormatUtilsTest {
+
+	@Test
+	void fixWindowsBugForGfj1Point1() {
+		fixWindowsBugTestcase("");
+		fixWindowsBugTestcase(
+				"",
+				"import somepackage;",
+				"");
+		fixWindowsBugTestcase(
+				"import somepackage;",
+				"",
+				"public class SomeClass {}");
+		fixWindowsBugTestcase(
+				"/** Some license */",
+				"import somepackage;",
+				"",
+				"public class SomeClass {}");
+		fixWindowsBugTestcase(
+				"package thispackage;",
+				"",
+				"import somepackage;",
+				"",
+				"public class SomeClass {}");
+		fixWindowsBugTestcase(
+				"/*",
+				" * A License.",
+				" */",
+				"",
+				"package thispackage;",
+				"",
+				"import somepackage;",
+				"",
+				"public class SomeClass {}");
+	}
+
+	private void fixWindowsBugTestcase(String... lines) {
+		String input = StringPrinter.buildStringFromLines(lines);
+		Assertions.assertEquals(input, GoogleJavaFormatUtils.fixWindowsBug(input, "1.1"));
+	}
+}
diff --git a/testlib/src/test/java/com/diffplug/spotless/java/GoogleJavaFormatStepTest.java b/testlib/src/test/java/com/diffplug/spotless/java/GoogleJavaFormatStepTest.java
index ff64b574e1..e2f15360f5 100644
--- a/testlib/src/test/java/com/diffplug/spotless/java/GoogleJavaFormatStepTest.java
+++ b/testlib/src/test/java/com/diffplug/spotless/java/GoogleJavaFormatStepTest.java
@@ -18,11 +18,9 @@
 import static org.junit.jupiter.api.condition.JRE.JAVA_13;
 import static org.junit.jupiter.api.condition.JRE.JAVA_15;
 
-import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.condition.EnabledForJreRange;
 
-import com.diffplug.common.base.StringPrinter;
 import com.diffplug.spotless.FormatterStep;
 import com.diffplug.spotless.Jvm;
 import com.diffplug.spotless.ResourceHarness;
@@ -147,42 +145,4 @@ protected FormatterStep create() {
 		}.testEquals();
 	}
 
-	@Test
-	void fixWindowsBugForGfj1Point1() {
-		fixWindowsBugTestcase("");
-		fixWindowsBugTestcase(
-				"",
-				"import somepackage;",
-				"");
-		fixWindowsBugTestcase(
-				"import somepackage;",
-				"",
-				"public class SomeClass {}");
-		fixWindowsBugTestcase(
-				"/** Some license */",
-				"import somepackage;",
-				"",
-				"public class SomeClass {}");
-		fixWindowsBugTestcase(
-				"package thispackage;",
-				"",
-				"import somepackage;",
-				"",
-				"public class SomeClass {}");
-		fixWindowsBugTestcase(
-				"/*",
-				" * A License.",
-				" */",
-				"",
-				"package thispackage;",
-				"",
-				"import somepackage;",
-				"",
-				"public class SomeClass {}");
-	}
-
-	private void fixWindowsBugTestcase(String... lines) {
-		String input = StringPrinter.buildStringFromLines(lines);
-		Assertions.assertEquals(input, GoogleJavaFormatStep.fixWindowsBug(input, "1.1"));
-	}
 }

From 30ef0d44e21f5a5ac7756eb700544075b99e5020 Mon Sep 17 00:00:00 2001
From: Simon Gamma <github@survive.ch>
Date: Sat, 4 Mar 2023 20:28:11 +0100
Subject: [PATCH 02/15] check minimum required formatter version

(we would need to implement specific glue code for older versions)
---
 .../main/java/com/diffplug/spotless/Jvm.java  | 89 +++++++++++++------
 .../spotless/java/GoogleJavaFormatStep.java   |  4 +-
 2 files changed, 66 insertions(+), 27 deletions(-)

diff --git a/lib/src/main/java/com/diffplug/spotless/Jvm.java b/lib/src/main/java/com/diffplug/spotless/Jvm.java
index c9c71b72df..fe8dc3e7a1 100644
--- a/lib/src/main/java/com/diffplug/spotless/Jvm.java
+++ b/lib/src/main/java/com/diffplug/spotless/Jvm.java
@@ -63,8 +63,9 @@ public static int version() {
 	public static class Support<V> {
 		private final String fmtName;
 		private final Comparator<? super V> fmtVersionComparator;
-		private final NavigableMap<Integer, V> jvm2fmtVersion;
-		private final NavigableMap<V, Integer> fmt2jvmVersion;
+		private final NavigableMap<Integer, V> jvm2fmtMaxVersion;
+		private final NavigableMap<Integer, V> jvm2fmtMinVersion;
+		private final NavigableMap<V, Integer> fmtMaxVersion2jvmVersion;
 
 		private Support(String fromatterName) {
 			this(fromatterName, new SemanticVersionComparator<V>());
@@ -73,40 +74,60 @@ private Support(String fromatterName) {
 		private Support(String formatterName, Comparator<? super V> formatterVersionComparator) {
 			fmtName = formatterName;
 			fmtVersionComparator = formatterVersionComparator;
-			jvm2fmtVersion = new TreeMap<Integer, V>();
-			fmt2jvmVersion = new TreeMap<V, Integer>(formatterVersionComparator);
+			jvm2fmtMaxVersion = new TreeMap<>();
+			jvm2fmtMinVersion = new TreeMap<>();
+			fmtMaxVersion2jvmVersion = new TreeMap<>(formatterVersionComparator);
 		}
 
 		/**
-		 * Add supported formatter version
+		 * Add maximum supported formatter version
 		 * @param minimumJvmVersion Minimum Java version required
 		 * @param maxFormatterVersion Maximum formatter version supported by the Java version
 		 * @return this
 		 */
 		public Support<V> add(int minimumJvmVersion, V maxFormatterVersion) {
 			Objects.requireNonNull(maxFormatterVersion);
-			if (null != jvm2fmtVersion.put(minimumJvmVersion, maxFormatterVersion)) {
+			if (null != jvm2fmtMaxVersion.put(minimumJvmVersion, maxFormatterVersion)) {
 				throw new IllegalArgumentException(String.format("Added duplicate entry for JVM %d+.", minimumJvmVersion));
 			}
-			if (null != fmt2jvmVersion.put(maxFormatterVersion, minimumJvmVersion)) {
+			if (null != fmtMaxVersion2jvmVersion.put(maxFormatterVersion, minimumJvmVersion)) {
 				throw new IllegalArgumentException(String.format("Added duplicate entry for formatter version %s.", maxFormatterVersion));
 			}
+			verifyVersionRangesDoNotIntersect(jvm2fmtMaxVersion, minimumJvmVersion, maxFormatterVersion);
+			return this;
+		}
+
+		public Support<V> addMin(int minimumJvmVersion, V minFormatterVersion) {
+			Objects.requireNonNull(minFormatterVersion);
+			if (null != jvm2fmtMinVersion.put(minimumJvmVersion, minFormatterVersion)) {
+				throw new IllegalArgumentException(String.format("Added duplicate entry for JVM %d+.", minimumJvmVersion));
+			}
+			verifyVersionRangesDoNotIntersect(jvm2fmtMinVersion, minimumJvmVersion, minFormatterVersion);
+			return this;
+		}
+
+		private void verifyVersionRangesDoNotIntersect(NavigableMap<Integer, V> jvm2fmtVersion, int minimumJvmVersion, V formatterVersion) {
 			Map.Entry<Integer, V> lower = jvm2fmtVersion.lowerEntry(minimumJvmVersion);
-			if ((null != lower) && (fmtVersionComparator.compare(maxFormatterVersion, lower.getValue()) <= 0)) {
-				throw new IllegalArgumentException(String.format("%d/%s should be lower than %d/%s", minimumJvmVersion, maxFormatterVersion, lower.getKey(), lower.getValue()));
+			if ((null != lower) && (fmtVersionComparator.compare(formatterVersion, lower.getValue()) <= 0)) {
+				throw new IllegalArgumentException(String.format("%d/%s should be lower than %d/%s", minimumJvmVersion, formatterVersion, lower.getKey(), lower.getValue()));
 			}
 			Map.Entry<Integer, V> higher = jvm2fmtVersion.higherEntry(minimumJvmVersion);
-			if ((null != higher) && (fmtVersionComparator.compare(maxFormatterVersion, higher.getValue()) >= 0)) {
-				throw new IllegalArgumentException(String.format("%d/%s should be higher than %d/%s", minimumJvmVersion, maxFormatterVersion, higher.getKey(), higher.getValue()));
+			if ((null != higher) && (fmtVersionComparator.compare(formatterVersion, higher.getValue()) >= 0)) {
+				throw new IllegalArgumentException(String.format("%d/%s should be higher than %d/%s", minimumJvmVersion, formatterVersion, higher.getKey(), higher.getValue()));
 			}
-			return this;
 		}
 
 		/** @return Highest formatter version recommended for this JVM (null, if JVM not supported) */
 		@Nullable
 		public V getRecommendedFormatterVersion() {
-			Integer configuredJvmVersionOrNull = jvm2fmtVersion.floorKey(Jvm.version());
-			return (null == configuredJvmVersionOrNull) ? null : jvm2fmtVersion.get(configuredJvmVersionOrNull);
+			Integer configuredJvmVersionOrNull = jvm2fmtMaxVersion.floorKey(Jvm.version());
+			return (null == configuredJvmVersionOrNull) ? null : jvm2fmtMaxVersion.get(configuredJvmVersionOrNull);
+		}
+
+		@Nullable
+		public V getMinimumRequiredFormatterVersion() {
+			Integer configuredJvmVersionOrNull = jvm2fmtMinVersion.floorKey(Jvm.version());
+			return (null == configuredJvmVersionOrNull) ? null : jvm2fmtMinVersion.get(configuredJvmVersionOrNull);
 		}
 
 		/**
@@ -123,10 +144,17 @@ public void assertFormatterSupported(V formatterVersion) {
 		}
 
 		private String buildUnsupportedFormatterMessage(V fmtVersion) {
+			// check if the jvm version is to low for the formatter version
 			int requiredJvmVersion = getRequiredJvmVersion(fmtVersion);
 			if (Jvm.version() < requiredJvmVersion) {
 				return buildUpgradeJvmMessage(fmtVersion) + "Upgrade your JVM or try " + toString();
 			}
+			// check if the formatter version is too low for the jvm version
+			V minimumFormatterVersion = getMinimumRequiredFormatterVersion();
+			if ((null != minimumFormatterVersion) && (fmtVersionComparator.compare(fmtVersion, minimumFormatterVersion) < 0)) {
+				return String.format("You are running Spotless on JVM %d, which requires %s of at least %s (you are using %s).%n", Jvm.version(), fmtName, minimumFormatterVersion, fmtVersion);
+			}
+			// otherwise all is well
 			return "";
 		}
 
@@ -137,7 +165,7 @@ private String buildUpgradeJvmMessage(V fmtVersion) {
 			if (null != recommendedFmtVersionOrNull) {
 				builder.append(String.format(", which limits you to %s %s.%n", fmtName, recommendedFmtVersionOrNull));
 			} else {
-				Entry<V, Integer> nextFmtVersionOrNull = fmt2jvmVersion.ceilingEntry(fmtVersion);
+				Entry<V, Integer> nextFmtVersionOrNull = fmtMaxVersion2jvmVersion.ceilingEntry(fmtVersion);
 				if (null != nextFmtVersionOrNull) {
 					builder.append(String.format(". %s %s requires JVM %d+", fmtName, fmtVersion, nextFmtVersionOrNull.getValue()));
 				}
@@ -147,12 +175,12 @@ private String buildUpgradeJvmMessage(V fmtVersion) {
 		}
 
 		private int getRequiredJvmVersion(V fmtVersion) {
-			Entry<V, Integer> entry = fmt2jvmVersion.ceilingEntry(fmtVersion);
+			Entry<V, Integer> entry = fmtMaxVersion2jvmVersion.ceilingEntry(fmtVersion);
 			if (null == entry) {
-				entry = fmt2jvmVersion.lastEntry();
+				entry = fmtMaxVersion2jvmVersion.lastEntry();
 			}
 			if (null != entry) {
-				V maxKnownFmtVersion = jvm2fmtVersion.get(entry.getValue());
+				V maxKnownFmtVersion = jvm2fmtMaxVersion.get(entry.getValue());
 				if (fmtVersionComparator.compare(fmtVersion, maxKnownFmtVersion) <= 0) {
 					return entry.getValue();
 				}
@@ -170,15 +198,15 @@ public FormatterFunc suggestLaterVersionOnError(V formatterVersion, FormatterFun
 			Objects.requireNonNull(formatterVersion);
 			Objects.requireNonNull(originalFunc);
 			final String hintUnsupportedProblem = buildUnsupportedFormatterMessage(formatterVersion);
-			final String proposeDiffererntFormatter = hintUnsupportedProblem.isEmpty() ? buildUpgradeFormatterMessage(formatterVersion) : hintUnsupportedProblem;
-			return proposeDiffererntFormatter.isEmpty() ? originalFunc : new FormatterFunc() {
+			final String proposeDifferentFormatter = hintUnsupportedProblem.isEmpty() ? buildUpgradeFormatterMessage(formatterVersion) : hintUnsupportedProblem;
+			return proposeDifferentFormatter.isEmpty() ? originalFunc : new FormatterFunc() {
 
 				@Override
 				public String apply(String unix, File file) throws Exception {
 					try {
 						return originalFunc.apply(unix, file);
 					} catch (Exception e) {
-						throw new Exception(proposeDiffererntFormatter, e);
+						throw new Exception(proposeDifferentFormatter, e);
 					}
 				}
 
@@ -187,7 +215,7 @@ public String apply(String input) throws Exception {
 					try {
 						return originalFunc.apply(input);
 					} catch (Exception e) {
-						throw new Exception(proposeDiffererntFormatter, e);
+						throw new Exception(proposeDifferentFormatter, e);
 					}
 				}
 
@@ -196,16 +224,25 @@ public String apply(String input) throws Exception {
 
 		private String buildUpgradeFormatterMessage(V fmtVersion) {
 			StringBuilder builder = new StringBuilder();
+			// check if the formatter is not supported on this jvm
+			V minimumFormatterVersion = getMinimumRequiredFormatterVersion();
 			V recommendedFmtVersionOrNull = getRecommendedFormatterVersion();
-			if (null != recommendedFmtVersionOrNull && (fmtVersionComparator.compare(fmtVersion, recommendedFmtVersionOrNull) < 0)) {
+			if ((null != minimumFormatterVersion) && (fmtVersionComparator.compare(fmtVersion, minimumFormatterVersion) < 0)) {
+				builder.append(String.format("You are running Spotless on JVM %d, which requires %s of at least %s.%n", Jvm.version(), fmtName, minimumFormatterVersion));
+				builder.append(String.format("You are using %s %s.%n", fmtName, fmtVersion));
+				if (null != recommendedFmtVersionOrNull) {
+					builder.append(String.format("%s %s is the recommended version, which may have fixed this problem.%n", fmtName, recommendedFmtVersionOrNull));
+				}
+				// check if the formatter is outdated on this jvm
+			} else if (null != recommendedFmtVersionOrNull && (fmtVersionComparator.compare(fmtVersion, recommendedFmtVersionOrNull) < 0)) {
 				builder.append(String.format("%s %s is currently being used, but outdated.%n", fmtName, fmtVersion));
 				builder.append(String.format("%s %s is the recommended version, which may have fixed this problem.%n", fmtName, recommendedFmtVersionOrNull));
 				builder.append(String.format("%s %s requires JVM %d+.", fmtName, recommendedFmtVersionOrNull, getRequiredJvmVersion(recommendedFmtVersionOrNull)));
 			} else {
-				V higherFormatterVersionOrNull = fmt2jvmVersion.higherKey(fmtVersion);
+				V higherFormatterVersionOrNull = fmtMaxVersion2jvmVersion.higherKey(fmtVersion);
 				if (null != higherFormatterVersionOrNull) {
 					builder.append(buildUpgradeJvmMessage(fmtVersion));
-					Integer higherJvmVersion = fmt2jvmVersion.get(higherFormatterVersionOrNull);
+					Integer higherJvmVersion = fmtMaxVersion2jvmVersion.get(higherFormatterVersionOrNull);
 					builder.append(String.format("If you upgrade your JVM to %d+, then you can use %s %s, which may have fixed this problem.", higherJvmVersion, fmtName, higherFormatterVersionOrNull));
 				}
 			}
@@ -215,7 +252,7 @@ private String buildUpgradeFormatterMessage(V fmtVersion) {
 		@Override
 		public String toString() {
 			return String.format("%s alternatives:%n", fmtName) +
-					jvm2fmtVersion.entrySet().stream().map(
+					jvm2fmtMaxVersion.entrySet().stream().map(
 							e -> String.format("- Version %s requires JVM %d+", e.getValue(), e.getKey())).collect(Collectors.joining(System.lineSeparator()));
 		}
 
diff --git a/lib/src/main/java/com/diffplug/spotless/java/GoogleJavaFormatStep.java b/lib/src/main/java/com/diffplug/spotless/java/GoogleJavaFormatStep.java
index 9a3b49c095..5ef33fd83a 100644
--- a/lib/src/main/java/com/diffplug/spotless/java/GoogleJavaFormatStep.java
+++ b/lib/src/main/java/com/diffplug/spotless/java/GoogleJavaFormatStep.java
@@ -69,7 +69,9 @@ public static FormatterStep create(String groupArtifact, String version, String
 				State::createFormat);
 	}
 
-	static final Jvm.Support<String> JVM_SUPPORT = Jvm.<String> support(NAME).add(11, "1.15.0");
+	static final Jvm.Support<String> JVM_SUPPORT = Jvm.<String> support(NAME)
+			.addMin(11, "1.8") // spotless requires java 11, so the min version of google java format we can support is 1.8
+			.add(11, "1.15.0"); // default version
 
 	public static String defaultGroupArtifact() {
 		return MAVEN_COORDINATE;

From 7355cb2ce341eaab5f695575cba505c2102c10e3 Mon Sep 17 00:00:00 2001
From: Simon Gamma <github@survive.ch>
Date: Sat, 4 Mar 2023 20:28:49 +0100
Subject: [PATCH 03/15] add test for min version check + adapt others

---
 .../main/java/com/diffplug/spotless/Jvm.java   |  4 ++--
 .../spotless/java/GoogleJavaFormatStep.java    |  2 +-
 .../googlejavaformat/JavaCodeFormatted.test    |  1 -
 .../JavaCodeFormattedAOSP.test                 |  1 -
 .../java/GoogleJavaFormatStepTest.java         | 18 +++++++++++++-----
 5 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/lib/src/main/java/com/diffplug/spotless/Jvm.java b/lib/src/main/java/com/diffplug/spotless/Jvm.java
index fe8dc3e7a1..7c9ad5b47a 100644
--- a/lib/src/main/java/com/diffplug/spotless/Jvm.java
+++ b/lib/src/main/java/com/diffplug/spotless/Jvm.java
@@ -152,7 +152,7 @@ private String buildUnsupportedFormatterMessage(V fmtVersion) {
 			// check if the formatter version is too low for the jvm version
 			V minimumFormatterVersion = getMinimumRequiredFormatterVersion();
 			if ((null != minimumFormatterVersion) && (fmtVersionComparator.compare(fmtVersion, minimumFormatterVersion) < 0)) {
-				return String.format("You are running Spotless on JVM %d, which requires %s of at least %s (you are using %s).%n", Jvm.version(), fmtName, minimumFormatterVersion, fmtVersion);
+				return String.format("You are running Spotless on JVM %d. This requires %s of at least %s (you are using %s).%n", Jvm.version(), fmtName, minimumFormatterVersion, fmtVersion);
 			}
 			// otherwise all is well
 			return "";
@@ -228,7 +228,7 @@ private String buildUpgradeFormatterMessage(V fmtVersion) {
 			V minimumFormatterVersion = getMinimumRequiredFormatterVersion();
 			V recommendedFmtVersionOrNull = getRecommendedFormatterVersion();
 			if ((null != minimumFormatterVersion) && (fmtVersionComparator.compare(fmtVersion, minimumFormatterVersion) < 0)) {
-				builder.append(String.format("You are running Spotless on JVM %d, which requires %s of at least %s.%n", Jvm.version(), fmtName, minimumFormatterVersion));
+				builder.append(String.format("You are running Spotless on JVM %d. This requires %s of at least %s.%n", Jvm.version(), fmtName, minimumFormatterVersion));
 				builder.append(String.format("You are using %s %s.%n", fmtName, fmtVersion));
 				if (null != recommendedFmtVersionOrNull) {
 					builder.append(String.format("%s %s is the recommended version, which may have fixed this problem.%n", fmtName, recommendedFmtVersionOrNull));
diff --git a/lib/src/main/java/com/diffplug/spotless/java/GoogleJavaFormatStep.java b/lib/src/main/java/com/diffplug/spotless/java/GoogleJavaFormatStep.java
index 5ef33fd83a..a3b9aad564 100644
--- a/lib/src/main/java/com/diffplug/spotless/java/GoogleJavaFormatStep.java
+++ b/lib/src/main/java/com/diffplug/spotless/java/GoogleJavaFormatStep.java
@@ -70,7 +70,7 @@ public static FormatterStep create(String groupArtifact, String version, String
 	}
 
 	static final Jvm.Support<String> JVM_SUPPORT = Jvm.<String> support(NAME)
-			.addMin(11, "1.8") // spotless requires java 11, so the min version of google java format we can support is 1.8
+			.addMin(11, "1.8") // we only support google-java-format >= 1.8 due to api changes
 			.add(11, "1.15.0"); // default version
 
 	public static String defaultGroupArtifact() {
diff --git a/testlib/src/main/resources/java/googlejavaformat/JavaCodeFormatted.test b/testlib/src/main/resources/java/googlejavaformat/JavaCodeFormatted.test
index 7f7483f1bc..7a83a0a12c 100644
--- a/testlib/src/main/resources/java/googlejavaformat/JavaCodeFormatted.test
+++ b/testlib/src/main/resources/java/googlejavaformat/JavaCodeFormatted.test
@@ -1,4 +1,3 @@
-
 import mylib.UsedA;
 import mylib.UsedB;
 
diff --git a/testlib/src/main/resources/java/googlejavaformat/JavaCodeFormattedAOSP.test b/testlib/src/main/resources/java/googlejavaformat/JavaCodeFormattedAOSP.test
index dd1493b8c8..25ccbc25f5 100644
--- a/testlib/src/main/resources/java/googlejavaformat/JavaCodeFormattedAOSP.test
+++ b/testlib/src/main/resources/java/googlejavaformat/JavaCodeFormattedAOSP.test
@@ -1,4 +1,3 @@
-
 import mylib.UsedA;
 import mylib.UsedB;
 
diff --git a/testlib/src/test/java/com/diffplug/spotless/java/GoogleJavaFormatStepTest.java b/testlib/src/test/java/com/diffplug/spotless/java/GoogleJavaFormatStepTest.java
index e2f15360f5..2cac245adc 100644
--- a/testlib/src/test/java/com/diffplug/spotless/java/GoogleJavaFormatStepTest.java
+++ b/testlib/src/test/java/com/diffplug/spotless/java/GoogleJavaFormatStepTest.java
@@ -51,7 +51,7 @@ void behavior18() throws Exception {
 
 	@Test
 	void behavior() throws Exception {
-		FormatterStep step = GoogleJavaFormatStep.create("1.2", TestProvisioner.mavenCentral());
+		FormatterStep step = GoogleJavaFormatStep.create("1.8", TestProvisioner.mavenCentral());
 		StepHarness.forStep(step)
 				.testResource("java/googlejavaformat/JavaCodeUnformatted.test", "java/googlejavaformat/JavaCodeFormatted.test")
 				.testResource("java/googlejavaformat/JavaCodeWithLicenseUnformatted.test", "java/googlejavaformat/JavaCodeWithLicenseFormatted.test")
@@ -60,8 +60,16 @@ void behavior() throws Exception {
 	}
 
 	@Test
-	void behaviorWithAospStyle() throws Exception {
+	void versionBelowMinimumRequiredVersionIsNotAllowed() throws Exception {
 		FormatterStep step = GoogleJavaFormatStep.create("1.2", "AOSP", TestProvisioner.mavenCentral());
+		StepHarness.forStep(step)
+				.testResourceExceptionMsg("java/googlejavaformat/JavaCodeWithLicenseUnformatted.test")
+				.contains("you are using 1.2");
+	}
+
+	@Test
+	void behaviorWithAospStyle() throws Exception {
+		FormatterStep step = GoogleJavaFormatStep.create("1.8", "AOSP", TestProvisioner.mavenCentral());
 		StepHarness.forStep(step)
 				.testResource("java/googlejavaformat/JavaCodeUnformatted.test", "java/googlejavaformat/JavaCodeFormattedAOSP.test")
 				.testResource("java/googlejavaformat/JavaCodeWithLicenseUnformatted.test", "java/googlejavaformat/JavaCodeWithLicenseFormattedAOSP.test")
@@ -83,7 +91,7 @@ void behaviorWithReflowLongStrings() throws Exception {
 
 	@Test
 	void behaviorWithCustomGroupArtifact() throws Exception {
-		FormatterStep step = GoogleJavaFormatStep.create(GoogleJavaFormatStep.defaultGroupArtifact(), "1.2", GoogleJavaFormatStep.defaultStyle(), TestProvisioner.mavenCentral(), false);
+		FormatterStep step = GoogleJavaFormatStep.create(GoogleJavaFormatStep.defaultGroupArtifact(), "1.8", GoogleJavaFormatStep.defaultStyle(), TestProvisioner.mavenCentral(), false);
 		StepHarness.forStep(step)
 				.testResource("java/googlejavaformat/JavaCodeUnformatted.test", "java/googlejavaformat/JavaCodeFormatted.test")
 				.testResource("java/googlejavaformat/JavaCodeWithLicenseUnformatted.test", "java/googlejavaformat/JavaCodeWithLicenseFormatted.test")
@@ -94,7 +102,7 @@ void behaviorWithCustomGroupArtifact() throws Exception {
 	@Test
 	void equality() throws Exception {
 		new SerializableEqualityTester() {
-			String version = "1.2";
+			String version = "1.8";
 			String style = "";
 			boolean reflowLongStrings = false;
 
@@ -103,7 +111,7 @@ protected void setupTest(API api) {
 				// same version == same
 				api.areDifferentThan();
 				// change the version, and it's different
-				version = "1.1";
+				version = "1.9";
 				api.areDifferentThan();
 				// change the style, and it's different
 				style = "AOSP";

From 25c4ab336a99b47ac31562abdf4688d765f2ffe4 Mon Sep 17 00:00:00 2001
From: Simon Gamma <github@survive.ch>
Date: Sun, 5 Mar 2023 20:01:44 +0100
Subject: [PATCH 04/15] adapt tests to new required min versions

---
 .../gradle/spotless/GoogleJavaFormatIntegrationTest.java  | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/GoogleJavaFormatIntegrationTest.java b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/GoogleJavaFormatIntegrationTest.java
index 1f5cb6af05..468ba527df 100644
--- a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/GoogleJavaFormatIntegrationTest.java
+++ b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/GoogleJavaFormatIntegrationTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016-2021 DiffPlug
+ * Copyright 2016-2023 DiffPlug
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -31,7 +31,7 @@ void integration() throws IOException {
 				"spotless {",
 				"    java {",
 				"        target file('test.java')",
-				"        googleJavaFormat('1.2')",
+				"        googleJavaFormat('1.8')",
 				"    }",
 				"}");
 
@@ -41,8 +41,8 @@ void integration() throws IOException {
 
 		checkRunsThenUpToDate();
 		replace("build.gradle",
-				"googleJavaFormat('1.2')",
-				"googleJavaFormat('1.3')");
+				"googleJavaFormat('1.8')",
+				"googleJavaFormat('1.9')");
 		checkRunsThenUpToDate();
 	}
 }

From a7c224294e12c0fac714764456ffe55b07444a59 Mon Sep 17 00:00:00 2001
From: Simon Gamma <github@survive.ch>
Date: Fri, 17 Mar 2023 09:25:40 +0100
Subject: [PATCH 05/15] gfj: bump default version to 1.16.0

---
 .../java/com/diffplug/spotless/java/GoogleJavaFormatStep.java   | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/src/main/java/com/diffplug/spotless/java/GoogleJavaFormatStep.java b/lib/src/main/java/com/diffplug/spotless/java/GoogleJavaFormatStep.java
index a3b9aad564..9f41175ab8 100644
--- a/lib/src/main/java/com/diffplug/spotless/java/GoogleJavaFormatStep.java
+++ b/lib/src/main/java/com/diffplug/spotless/java/GoogleJavaFormatStep.java
@@ -71,7 +71,7 @@ public static FormatterStep create(String groupArtifact, String version, String
 
 	static final Jvm.Support<String> JVM_SUPPORT = Jvm.<String> support(NAME)
 			.addMin(11, "1.8") // we only support google-java-format >= 1.8 due to api changes
-			.add(11, "1.15.0"); // default version
+			.add(11, "1.16.0"); // default version
 
 	public static String defaultGroupArtifact() {
 		return MAVEN_COORDINATE;

From e4ec8a55d38d91d580c302f98e8990948599d4f4 Mon Sep 17 00:00:00 2001
From: Simon Gamma <github@survive.ch>
Date: Fri, 17 Mar 2023 09:29:53 +0100
Subject: [PATCH 06/15] add gjf conversion to CHANGES.md files

---
 CHANGES.md               | 3 +++
 plugin-gradle/CHANGES.md | 3 +++
 plugin-maven/CHANGES.md  | 3 +++
 3 files changed, 9 insertions(+)

diff --git a/CHANGES.md b/CHANGES.md
index c0deba72dc..f25f24ac3a 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -10,6 +10,9 @@ This document is intended for Spotless developers.
 We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (starting after version `1.27.0`).
 
 ## [Unreleased]
+### Changes
+* **POTENTIALLY BREAKING** Converted `googleJavaFormat` to a compile-only dependency and drop support for versions &lt; `1.8`. ([#9999](https://github.com/diffplug/spotless/pull/9999))
+* Bump default `googleJavaFormat` version `1.15.0` -> `1.16.0`. ([#9999](https://github.com/diffplug/spotless/pull/9999))
 
 ## [2.37.0] - 2023-03-13
 ### Added
diff --git a/plugin-gradle/CHANGES.md b/plugin-gradle/CHANGES.md
index 2c85978621..eeb68f2cc5 100644
--- a/plugin-gradle/CHANGES.md
+++ b/plugin-gradle/CHANGES.md
@@ -3,6 +3,9 @@
 We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (starting after version `3.27.0`).
 
 ## [Unreleased]
+### Changes
+* **POTENTIALLY BREAKING** Drop support for `googleJavaFormat` versions &lt; `1.8`. ([#9999](https://github.com/diffplug/spotless/pull/9999))
+* Bump default `googleJavaFormat` version `1.15.0` -> `1.16.0`. ([#9999](https://github.com/diffplug/spotless/pull/9999))
 
 ## [6.17.0] - 2023-03-13
 ### Added
diff --git a/plugin-maven/CHANGES.md b/plugin-maven/CHANGES.md
index 33e85b9f26..ac39f49d27 100644
--- a/plugin-maven/CHANGES.md
+++ b/plugin-maven/CHANGES.md
@@ -3,6 +3,9 @@
 We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (starting after version `1.27.0`).
 
 ## [Unreleased]
+### Changes
+* **POTENTIALLY BREAKING** Drop support for `googleJavaFormat` versions &lt; `1.8`. ([#9999](https://github.com/diffplug/spotless/pull/9999))
+* Bump default `googleJavaFormat` version `1.15.0` -> `1.16.0`. ([#9999](https://github.com/diffplug/spotless/pull/9999))
 
 ## [2.35.0] - 2023-03-13
 ### Added

From b907a8870f740bb987a8675334ab6965e807550d Mon Sep 17 00:00:00 2001
From: Simon Gamma <github@survive.ch>
Date: Fri, 17 Mar 2023 09:34:57 +0100
Subject: [PATCH 07/15] adapt min. required GJF versions in READMEs

---
 plugin-gradle/README.md | 4 ++--
 plugin-maven/README.md  | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/plugin-gradle/README.md b/plugin-gradle/README.md
index fffdb38518..616aacdb1f 100644
--- a/plugin-gradle/README.md
+++ b/plugin-gradle/README.md
@@ -187,8 +187,8 @@ spotless {
 spotless {
   java {
     googleJavaFormat()
-    // optional: you can specify a specific version and/or switch to AOSP style
-    //   and/or reflow long strings (requires at least 1.8)
+    // optional: you can specify a specific version (>= 1.8) and/or switch to AOSP style
+    //   and/or reflow long strings
     //   and/or use custom group artifact (you probably don't need this)
     googleJavaFormat('1.8').aosp().reflowLongStrings().groupArtifact('com.google.googlejavaformat:google-java-format')
 ```
diff --git a/plugin-maven/README.md b/plugin-maven/README.md
index 6d13bc87f3..5971721e24 100644
--- a/plugin-maven/README.md
+++ b/plugin-maven/README.md
@@ -213,9 +213,9 @@ any other maven phase (i.e. compile) then it can be configured as below;
 
 ```xml
 <googleJavaFormat>
-  <version>1.8</version>                      <!-- optional -->
+  <version>1.8</version>                      <!-- optional, 1.8 is minimum supported version -->
   <style>GOOGLE</style>                       <!-- or AOSP (optional) -->
-  <reflowLongStrings>true</reflowLongStrings> <!-- optional (requires at least 1.8) -->
+  <reflowLongStrings>true</reflowLongStrings> <!-- optional -->
   <!-- optional: custom group artifact (you probably don't need this) -->
   <groupArtifact>com.google.googlejavaformat:google-java-format</groupArtifact>
 </googleJavaFormat>

From 94eaa5efc87e1a1d34d5b89d9b8db28ed1b45c65 Mon Sep 17 00:00:00 2001
From: Simon Gamma <github@survive.ch>
Date: Fri, 17 Mar 2023 09:45:01 +0100
Subject: [PATCH 08/15] adapt to actual PR number

---
 CHANGES.md               | 4 ++--
 plugin-gradle/CHANGES.md | 4 ++--
 plugin-maven/CHANGES.md  | 4 ++--
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/CHANGES.md b/CHANGES.md
index f25f24ac3a..ec06be1db5 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -11,8 +11,8 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (
 
 ## [Unreleased]
 ### Changes
-* **POTENTIALLY BREAKING** Converted `googleJavaFormat` to a compile-only dependency and drop support for versions &lt; `1.8`. ([#9999](https://github.com/diffplug/spotless/pull/9999))
-* Bump default `googleJavaFormat` version `1.15.0` -> `1.16.0`. ([#9999](https://github.com/diffplug/spotless/pull/9999))
+* **POTENTIALLY BREAKING** Converted `googleJavaFormat` to a compile-only dependency and drop support for versions &lt; `1.8`. ([#1630](https://github.com/diffplug/spotless/pull/1630))
+* Bump default `googleJavaFormat` version `1.15.0` -> `1.16.0`. ([#1630](https://github.com/diffplug/spotless/pull/1630))
 
 ## [2.37.0] - 2023-03-13
 ### Added
diff --git a/plugin-gradle/CHANGES.md b/plugin-gradle/CHANGES.md
index eeb68f2cc5..ef7b1b8dae 100644
--- a/plugin-gradle/CHANGES.md
+++ b/plugin-gradle/CHANGES.md
@@ -4,8 +4,8 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (
 
 ## [Unreleased]
 ### Changes
-* **POTENTIALLY BREAKING** Drop support for `googleJavaFormat` versions &lt; `1.8`. ([#9999](https://github.com/diffplug/spotless/pull/9999))
-* Bump default `googleJavaFormat` version `1.15.0` -> `1.16.0`. ([#9999](https://github.com/diffplug/spotless/pull/9999))
+* **POTENTIALLY BREAKING** Drop support for `googleJavaFormat` versions &lt; `1.8`. ([#1630](https://github.com/diffplug/spotless/pull/1630))
+* Bump default `googleJavaFormat` version `1.15.0` -> `1.16.0`. ([#1630](https://github.com/diffplug/spotless/pull/1630))
 
 ## [6.17.0] - 2023-03-13
 ### Added
diff --git a/plugin-maven/CHANGES.md b/plugin-maven/CHANGES.md
index ac39f49d27..421b5e56e7 100644
--- a/plugin-maven/CHANGES.md
+++ b/plugin-maven/CHANGES.md
@@ -4,8 +4,8 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (
 
 ## [Unreleased]
 ### Changes
-* **POTENTIALLY BREAKING** Drop support for `googleJavaFormat` versions &lt; `1.8`. ([#9999](https://github.com/diffplug/spotless/pull/9999))
-* Bump default `googleJavaFormat` version `1.15.0` -> `1.16.0`. ([#9999](https://github.com/diffplug/spotless/pull/9999))
+* **POTENTIALLY BREAKING** Drop support for `googleJavaFormat` versions &lt; `1.8`. ([#1630](https://github.com/diffplug/spotless/pull/1630))
+* Bump default `googleJavaFormat` version `1.15.0` -> `1.16.0`. ([#1630](https://github.com/diffplug/spotless/pull/1630))
 
 ## [2.35.0] - 2023-03-13
 ### Added

From cb0fd38fa4c8f2446a4832b70c3d9abee37b52ca Mon Sep 17 00:00:00 2001
From: Simon Gamma <github@survive.ch>
Date: Fri, 17 Mar 2023 11:06:17 +0100
Subject: [PATCH 09/15] adaptions to min-required gjf version

---
 .../gradle/spotless/ConfigAvoidanceTest.java     |  4 ++--
 .../gradle/spotless/ConfigurationCacheTest.java  |  8 ++++----
 .../gradle/spotless/FilePermissionsTest.java     |  4 ++--
 .../gradle/spotless/IndependentTaskTest.java     |  4 ++--
 .../gradle/spotless/JavaDefaultTargetTest.java   |  4 ++--
 .../gradle/spotless/MultiProjectTest.java        | 16 ++++++++--------
 .../spotless/RegisterDependenciesTaskTest.java   |  6 +++---
 .../gradle/spotless/WithinBlockTest.java         |  6 +++---
 8 files changed, 26 insertions(+), 26 deletions(-)

diff --git a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/ConfigAvoidanceTest.java b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/ConfigAvoidanceTest.java
index d5422a3631..bd521bd864 100644
--- a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/ConfigAvoidanceTest.java
+++ b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/ConfigAvoidanceTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016-2021 DiffPlug
+ * Copyright 2016-2023 DiffPlug
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -31,7 +31,7 @@ void noConfigOnHelp() throws IOException {
 				"apply plugin: 'java'",
 				"spotless {",
 				"    java {",
-				"        googleJavaFormat('1.2')",
+				"        googleJavaFormat()",
 				"    }",
 				"}",
 				"",
diff --git a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/ConfigurationCacheTest.java b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/ConfigurationCacheTest.java
index 4006752af2..396a884cc5 100644
--- a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/ConfigurationCacheTest.java
+++ b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/ConfigurationCacheTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2020-2022 DiffPlug
+ * Copyright 2020-2023 DiffPlug
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -39,7 +39,7 @@ public void helpConfigures() throws IOException {
 				"apply plugin: 'java'",
 				"spotless {",
 				"    java {",
-				"        googleJavaFormat('1.2')",
+				"        googleJavaFormat()",
 				"    }",
 				"}");
 		gradleRunner().withArguments("help").build();
@@ -55,7 +55,7 @@ public void helpConfiguresIfTasksAreCreated() throws IOException {
 				"apply plugin: 'java'",
 				"spotless {",
 				"    java {",
-				"        googleJavaFormat('1.2')",
+				"        googleJavaFormat()",
 				"    }",
 				"}",
 				"tasks.named('spotlessJavaApply').get()");
@@ -72,7 +72,7 @@ public void jvmLocalCache() throws IOException {
 				"spotless {",
 				"    java {",
 				"        target file('test.java')",
-				"        googleJavaFormat('1.2')",
+				"        googleJavaFormat()",
 				"    }",
 				"}");
 
diff --git a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/FilePermissionsTest.java b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/FilePermissionsTest.java
index a5ce2d11cd..d342348a5b 100644
--- a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/FilePermissionsTest.java
+++ b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/FilePermissionsTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2020-2021 DiffPlug
+ * Copyright 2020-2023 DiffPlug
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -40,7 +40,7 @@ void spotlessApplyShouldPreservePermissions() throws IOException {
 				"spotless {",
 				"    java {",
 				"        target file('test.java')",
-				"        googleJavaFormat('1.2')",
+				"        googleJavaFormat()",
 				"    }",
 				"}");
 		setFile("test.java").toResource("java/googlejavaformat/JavaCodeUnformatted.test");
diff --git a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/IndependentTaskTest.java b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/IndependentTaskTest.java
index 459b871b94..4062aae51d 100644
--- a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/IndependentTaskTest.java
+++ b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/IndependentTaskTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016-2021 DiffPlug
+ * Copyright 2016-2023 DiffPlug
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -32,7 +32,7 @@ void independent() throws IOException {
 				"",
 				"def underTest = new JavaExtension(spotless)",
 				"underTest.target file('test.java')",
-				"underTest.googleJavaFormat('1.2')",
+				"underTest.googleJavaFormat()",
 				"",
 				"def independent = underTest.createIndependentApplyTask('independent')");
 		setFile("test.java").toResource("java/googlejavaformat/JavaCodeUnformatted.test");
diff --git a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/JavaDefaultTargetTest.java b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/JavaDefaultTargetTest.java
index 898008c27a..e6569b2647 100644
--- a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/JavaDefaultTargetTest.java
+++ b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/JavaDefaultTargetTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016-2021 DiffPlug
+ * Copyright 2016-2023 DiffPlug
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -32,7 +32,7 @@ void integration() throws IOException {
 				"",
 				"spotless {",
 				"    java {",
-				"        googleJavaFormat('1.2')",
+				"        googleJavaFormat()",
 				"    }",
 				"}");
 		setFile("src/main/java/test.java").toResource("java/googlejavaformat/JavaCodeUnformatted.test");
diff --git a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/MultiProjectTest.java b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/MultiProjectTest.java
index 086a2ddb1d..98761b472a 100644
--- a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/MultiProjectTest.java
+++ b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/MultiProjectTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016-2021 DiffPlug
+ * Copyright 2016-2023 DiffPlug
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -47,7 +47,7 @@ void createSubproject(String name) throws IOException {
 				"spotless {",
 				"    java {",
 				"        target file('test.java')",
-				"        googleJavaFormat('1.2')",
+				"        googleJavaFormat('1.16.0')",
 				"    }",
 				"}");
 		setFile(name + "/test.java").toResource("java/googlejavaformat/JavaCodeUnformatted.test");
@@ -71,7 +71,7 @@ public void hasRootSpotless() throws IOException {
 				"spotless {",
 				"    java {",
 				"        target file('test.java')",
-				"        googleJavaFormat('1.2')",
+				"        googleJavaFormat('1.16.0')",
 				"    }",
 				"}");
 		setFile("test.java").toResource("java/googlejavaformat/JavaCodeUnformatted.test");
@@ -88,7 +88,7 @@ public void predeclaredFails() throws IOException {
 				"spotless { predeclareDeps() }");
 		createNSubprojects();
 		Assertions.assertThat(gradleRunner().withArguments("spotlessApply").buildAndFail().getOutput())
-				.contains("Add a step with [com.google.googlejavaformat:google-java-format:1.2] into the `spotlessPredeclare` block in the root project.");
+				.contains("Add a step with [com.google.googlejavaformat:google-java-format:1.16.0] into the `spotlessPredeclare` block in the root project.");
 	}
 
 	@Test
@@ -100,7 +100,7 @@ public void predeclaredSucceeds() throws IOException {
 				"repositories { mavenCentral() }",
 				"spotless { predeclareDeps() }",
 				"spotlessPredeclare {",
-				" java { googleJavaFormat('1.2') }",
+				" java { googleJavaFormat('1.16.0') }",
 				"}");
 		createNSubprojects();
 		gradleRunner().withArguments("spotlessApply").build();
@@ -115,7 +115,7 @@ public void predeclaredFromBuildscriptSucceeds() throws IOException {
 				"repositories { mavenCentral() }",
 				"spotless { predeclareDepsFromBuildscript() }",
 				"spotlessPredeclare {",
-				" java { googleJavaFormat('1.2') }",
+				" java { googleJavaFormat('1.16.0') }",
 				"}");
 		createNSubprojects();
 		gradleRunner().withArguments("spotlessApply").build();
@@ -129,7 +129,7 @@ public void predeclaredOrdering() throws IOException {
 				"}",
 				"repositories { mavenCentral() }",
 				"spotlessPredeclare {",
-				" java { googleJavaFormat('1.2') }",
+				" java { googleJavaFormat('1.16.0') }",
 				"}",
 				"spotless { predeclareDepsFromBuildscript() }");
 		createNSubprojects();
@@ -145,7 +145,7 @@ public void predeclaredUndeclared() throws IOException {
 				"}",
 				"repositories { mavenCentral() }",
 				"spotlessPredeclare {",
-				" java { googleJavaFormat('1.2') }",
+				" java { googleJavaFormat('1.16.0') }",
 				"}");
 		createNSubprojects();
 		Assertions.assertThat(gradleRunner().withArguments("spotlessApply").buildAndFail().getOutput())
diff --git a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/RegisterDependenciesTaskTest.java b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/RegisterDependenciesTaskTest.java
index 480de4f01b..76d0449060 100644
--- a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/RegisterDependenciesTaskTest.java
+++ b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/RegisterDependenciesTaskTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016-2021 DiffPlug
+ * Copyright 2016-2023 DiffPlug
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -32,11 +32,11 @@ void duplicateConfigs() throws IOException {
 				"spotless {",
 				"  java {",
 				"    target 'src/main/java/**/*.java'",
-				"    googleJavaFormat('1.2')",
+				"    googleJavaFormat()",
 				"  }",
 				"  format 'javaDupe', com.diffplug.gradle.spotless.JavaExtension, {",
 				"    target 'src/boop/java/**/*.java'",
-				"    googleJavaFormat('1.2')",
+				"    googleJavaFormat()",
 				"  }",
 				"}");
 
diff --git a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/WithinBlockTest.java b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/WithinBlockTest.java
index 01fb048b66..d1df8b5f96 100644
--- a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/WithinBlockTest.java
+++ b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/WithinBlockTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2020-2022 DiffPlug
+ * Copyright 2020-2023 DiffPlug
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -31,7 +31,7 @@ void genericFormatTest() throws IOException {
 				"spotless {",
 				"  format 'customJava', JavaExtension, {",
 				"    target '*.java'",
-				"    googleJavaFormat('1.2')",
+				"    googleJavaFormat()",
 				"  }",
 				"}");
 		setFile("test.java").toResource("java/googlejavaformat/JavaCodeUnformatted.test");
@@ -53,7 +53,7 @@ void withinBlocksTourDeForce() throws IOException {
 				"      custom 'lowercase', { str -> str.toLowerCase() }",
 				"    }",
 				"    withinBlocks 'java only', '\\n```java\\n', '\\n```\\n', JavaExtension, {",
-				"      googleJavaFormat('1.2')",
+				"      googleJavaFormat()",
 				"    }",
 				"  }",
 				"}");

From 048947b20ef8ad7111efea8c11b94482b05a4548 Mon Sep 17 00:00:00 2001
From: Simon Gamma <github@survive.ch>
Date: Fri, 17 Mar 2023 13:40:45 +0100
Subject: [PATCH 10/15] adapt more gjf format specifications

---
 .../spotless/java/GoogleJavaFormatStep.java   |  1 +
 .../spotless/maven/MavenProvisionerTest.java  |  2 +-
 .../spotless/maven/SpecificFilesTest.java     |  4 ++--
 .../maven/java/GoogleJavaFormatTest.java      |  6 +++---
 .../java/GoogleJavaFormatStepTest.java        | 20 ++++++++++++++-----
 5 files changed, 22 insertions(+), 11 deletions(-)

diff --git a/lib/src/main/java/com/diffplug/spotless/java/GoogleJavaFormatStep.java b/lib/src/main/java/com/diffplug/spotless/java/GoogleJavaFormatStep.java
index 9f41175ab8..d7ba26f384 100644
--- a/lib/src/main/java/com/diffplug/spotless/java/GoogleJavaFormatStep.java
+++ b/lib/src/main/java/com/diffplug/spotless/java/GoogleJavaFormatStep.java
@@ -71,6 +71,7 @@ public static FormatterStep create(String groupArtifact, String version, String
 
 	static final Jvm.Support<String> JVM_SUPPORT = Jvm.<String> support(NAME)
 			.addMin(11, "1.8") // we only support google-java-format >= 1.8 due to api changes
+			.addMin(16, "1.10.0") // java 16 requires at least 1.10.0 due to jdk api changes in JavaTokenizer
 			.add(11, "1.16.0"); // default version
 
 	public static String defaultGroupArtifact() {
diff --git a/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenProvisionerTest.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenProvisionerTest.java
index cabbf7c5c0..5af146c736 100644
--- a/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenProvisionerTest.java
+++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenProvisionerTest.java
@@ -33,7 +33,7 @@ void testMultipleDependenciesExcludingTransitives() throws Exception {
 	void testSingleDependencyIncludingTransitives() throws Exception {
 		writePomWithJavaSteps(
 				"<googleJavaFormat>",
-				"  <version>1.2</version>",
+				"  <version>1.10.0</version>",
 				"</googleJavaFormat>");
 		assertResolveDependenciesWorks();
 	}
diff --git a/plugin-maven/src/test/java/com/diffplug/spotless/maven/SpecificFilesTest.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/SpecificFilesTest.java
index 55cd586582..11cca5994a 100644
--- a/plugin-maven/src/test/java/com/diffplug/spotless/maven/SpecificFilesTest.java
+++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/SpecificFilesTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016-2021 DiffPlug
+ * Copyright 2016-2023 DiffPlug
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -58,7 +58,7 @@ private void integration(String patterns, boolean firstFormatted, boolean second
 				"  <include>src/**/java/**/*.java</include>",
 				"</includes>",
 				"<googleJavaFormat>",
-				"  <version>1.2</version>",
+				"  <version>1.10.0</version>",
 				"</googleJavaFormat>");
 
 		setFile(testFile(1)).toResource(fixture(false));
diff --git a/plugin-maven/src/test/java/com/diffplug/spotless/maven/java/GoogleJavaFormatTest.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/java/GoogleJavaFormatTest.java
index 98a83d612c..407d089999 100644
--- a/plugin-maven/src/test/java/com/diffplug/spotless/maven/java/GoogleJavaFormatTest.java
+++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/java/GoogleJavaFormatTest.java
@@ -24,7 +24,7 @@ class GoogleJavaFormatTest extends MavenIntegrationHarness {
 	void specificVersionDefaultStyle() throws Exception {
 		writePomWithJavaSteps(
 				"<googleJavaFormat>",
-				"  <version>1.2</version>",
+				"  <version>1.10.0</version>",
 				"</googleJavaFormat>");
 
 		runTest("java/googlejavaformat/JavaCodeFormatted.test");
@@ -34,7 +34,7 @@ void specificVersionDefaultStyle() throws Exception {
 	void specificVersionSpecificStyle() throws Exception {
 		writePomWithJavaSteps(
 				"<googleJavaFormat>",
-				"  <version>1.2</version>",
+				"  <version>1.10.0</version>",
 				"  <style>AOSP</style>",
 				"</googleJavaFormat>");
 
@@ -45,7 +45,7 @@ void specificVersionSpecificStyle() throws Exception {
 	void specificVersionReflowLongStrings() throws Exception {
 		writePomWithJavaSteps(
 				"<googleJavaFormat>",
-				"  <version>1.8</version>",
+				"  <version>1.10.0</version>",
 				"  <reflowLongStrings>true</reflowLongStrings>",
 				"</googleJavaFormat>");
 
diff --git a/testlib/src/test/java/com/diffplug/spotless/java/GoogleJavaFormatStepTest.java b/testlib/src/test/java/com/diffplug/spotless/java/GoogleJavaFormatStepTest.java
index 2cac245adc..694e390727 100644
--- a/testlib/src/test/java/com/diffplug/spotless/java/GoogleJavaFormatStepTest.java
+++ b/testlib/src/test/java/com/diffplug/spotless/java/GoogleJavaFormatStepTest.java
@@ -17,6 +17,7 @@
 
 import static org.junit.jupiter.api.condition.JRE.JAVA_13;
 import static org.junit.jupiter.api.condition.JRE.JAVA_15;
+import static org.junit.jupiter.api.condition.JRE.JAVA_16;
 
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.condition.EnabledForJreRange;
@@ -51,7 +52,7 @@ void behavior18() throws Exception {
 
 	@Test
 	void behavior() throws Exception {
-		FormatterStep step = GoogleJavaFormatStep.create("1.8", TestProvisioner.mavenCentral());
+		FormatterStep step = GoogleJavaFormatStep.create("1.10.0", TestProvisioner.mavenCentral());
 		StepHarness.forStep(step)
 				.testResource("java/googlejavaformat/JavaCodeUnformatted.test", "java/googlejavaformat/JavaCodeFormatted.test")
 				.testResource("java/googlejavaformat/JavaCodeWithLicenseUnformatted.test", "java/googlejavaformat/JavaCodeWithLicenseFormatted.test")
@@ -67,9 +68,18 @@ void versionBelowMinimumRequiredVersionIsNotAllowed() throws Exception {
 				.contains("you are using 1.2");
 	}
 
+	@Test
+	@EnabledForJreRange(min = JAVA_16)
+	void versionBelowOneDotTenIsNotAllowed() throws Exception {
+		FormatterStep step = GoogleJavaFormatStep.create("1.9", "AOSP", TestProvisioner.mavenCentral());
+		StepHarness.forStep(step)
+				.testResourceExceptionMsg("java/googlejavaformat/JavaCodeWithLicenseUnformatted.test")
+				.contains("you are using 1.9");
+	}
+
 	@Test
 	void behaviorWithAospStyle() throws Exception {
-		FormatterStep step = GoogleJavaFormatStep.create("1.8", "AOSP", TestProvisioner.mavenCentral());
+		FormatterStep step = GoogleJavaFormatStep.create("1.10.0", "AOSP", TestProvisioner.mavenCentral());
 		StepHarness.forStep(step)
 				.testResource("java/googlejavaformat/JavaCodeUnformatted.test", "java/googlejavaformat/JavaCodeFormattedAOSP.test")
 				.testResource("java/googlejavaformat/JavaCodeWithLicenseUnformatted.test", "java/googlejavaformat/JavaCodeWithLicenseFormattedAOSP.test")
@@ -91,7 +101,7 @@ void behaviorWithReflowLongStrings() throws Exception {
 
 	@Test
 	void behaviorWithCustomGroupArtifact() throws Exception {
-		FormatterStep step = GoogleJavaFormatStep.create(GoogleJavaFormatStep.defaultGroupArtifact(), "1.8", GoogleJavaFormatStep.defaultStyle(), TestProvisioner.mavenCentral(), false);
+		FormatterStep step = GoogleJavaFormatStep.create(GoogleJavaFormatStep.defaultGroupArtifact(), "1.10.0", GoogleJavaFormatStep.defaultStyle(), TestProvisioner.mavenCentral(), false);
 		StepHarness.forStep(step)
 				.testResource("java/googlejavaformat/JavaCodeUnformatted.test", "java/googlejavaformat/JavaCodeFormatted.test")
 				.testResource("java/googlejavaformat/JavaCodeWithLicenseUnformatted.test", "java/googlejavaformat/JavaCodeWithLicenseFormatted.test")
@@ -102,7 +112,7 @@ void behaviorWithCustomGroupArtifact() throws Exception {
 	@Test
 	void equality() throws Exception {
 		new SerializableEqualityTester() {
-			String version = "1.8";
+			String version = "1.10.0";
 			String style = "";
 			boolean reflowLongStrings = false;
 
@@ -111,7 +121,7 @@ protected void setupTest(API api) {
 				// same version == same
 				api.areDifferentThan();
 				// change the version, and it's different
-				version = "1.9";
+				version = "1.11.0";
 				api.areDifferentThan();
 				// change the style, and it's different
 				style = "AOSP";

From b0adcfaadeaf96d11266c36187720dc0f87cea94 Mon Sep 17 00:00:00 2001
From: Simon Gamma <github@survive.ch>
Date: Fri, 17 Mar 2023 13:42:52 +0100
Subject: [PATCH 11/15] clarify comment

---
 lib/build.gradle | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/build.gradle b/lib/build.gradle
index e939f7249e..19bc98f710 100644
--- a/lib/build.gradle
+++ b/lib/build.gradle
@@ -81,7 +81,7 @@ dependencies {
 
 	palantirJavaFormatCompileOnly 'com.palantir.javaformat:palantir-java-format:1.1.0' 	// this version needs to stay compilable against Java 8 for CI Job testNpm
 
-	googleJavaFormatCompileOnly 'com.google.googlejavaformat:google-java-format:1.8' // minimum required version for jdk 11
+	googleJavaFormatCompileOnly 'com.google.googlejavaformat:google-java-format:1.8' // minimum required version due to api changes before then
 	testGoogleJavaFormatImplementation "com.diffplug.durian:durian-core:$VER_DURIAN"
 
 	// used jackson-based formatters

From ab982d2480d36a29d32ae0b2ed6063153295ad5e Mon Sep 17 00:00:00 2001
From: Simon Gamma <github@survive.ch>
Date: Fri, 17 Mar 2023 14:01:17 +0100
Subject: [PATCH 12/15] another pinned version to be upgraded

---
 .../gradle/spotless/GoogleJavaFormatIntegrationTest.java    | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/GoogleJavaFormatIntegrationTest.java b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/GoogleJavaFormatIntegrationTest.java
index 468ba527df..5c7fe54f59 100644
--- a/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/GoogleJavaFormatIntegrationTest.java
+++ b/plugin-gradle/src/test/java/com/diffplug/gradle/spotless/GoogleJavaFormatIntegrationTest.java
@@ -31,7 +31,7 @@ void integration() throws IOException {
 				"spotless {",
 				"    java {",
 				"        target file('test.java')",
-				"        googleJavaFormat('1.8')",
+				"        googleJavaFormat('1.10.0')",
 				"    }",
 				"}");
 
@@ -41,8 +41,8 @@ void integration() throws IOException {
 
 		checkRunsThenUpToDate();
 		replace("build.gradle",
-				"googleJavaFormat('1.8')",
-				"googleJavaFormat('1.9')");
+				"googleJavaFormat('1.10.0')",
+				"googleJavaFormat()");
 		checkRunsThenUpToDate();
 	}
 }

From abe30b897345fd973f0506e8c77e8849f99c37fa Mon Sep 17 00:00:00 2001
From: Simon Gamma <github@survive.ch>
Date: Sat, 18 Mar 2023 09:36:49 +0100
Subject: [PATCH 13/15] remove obsolete fix code

PR Feedback: this version is no longer supported anyway
---
 .../java/GoogleJavaFormatFormatterFunc.java   |  5 +-
 ...rmatRemoveUnusedImporterFormatterFunc.java |  5 +-
 .../glue/java/GoogleJavaFormatUtils.java      | 54 ----------------
 .../glue/java/GoogleJavaFormatUtilsTest.java  | 63 -------------------
 4 files changed, 2 insertions(+), 125 deletions(-)
 delete mode 100644 lib/src/googleJavaFormat/java/com/diffplug/spotless/glue/java/GoogleJavaFormatUtils.java
 delete mode 100644 lib/src/testGoogleJavaFormat/java/com/diffplug/spotless/glue/java/GoogleJavaFormatUtilsTest.java

diff --git a/lib/src/googleJavaFormat/java/com/diffplug/spotless/glue/java/GoogleJavaFormatFormatterFunc.java b/lib/src/googleJavaFormat/java/com/diffplug/spotless/glue/java/GoogleJavaFormatFormatterFunc.java
index a326cf1f69..97d31da268 100644
--- a/lib/src/googleJavaFormat/java/com/diffplug/spotless/glue/java/GoogleJavaFormatFormatterFunc.java
+++ b/lib/src/googleJavaFormat/java/com/diffplug/spotless/glue/java/GoogleJavaFormatFormatterFunc.java
@@ -15,8 +15,6 @@
  */
 package com.diffplug.spotless.glue.java;
 
-import static com.diffplug.spotless.glue.java.GoogleJavaFormatUtils.fixWindowsBug;
-
 import java.util.Objects;
 
 import javax.annotation.Nonnull;
@@ -57,8 +55,7 @@ public String apply(@Nonnull String input) throws Exception {
 		String formatted = formatter.formatSource(input);
 		String removedUnused = RemoveUnusedImports.removeUnusedImports(formatted);
 		String sortedImports = ImportOrderer.reorderImports(removedUnused, formatterStyle);
-		String reflowedLongStrings = reflowLongStrings(sortedImports);
-		return fixWindowsBug(reflowedLongStrings, version);
+		return reflowLongStrings(sortedImports);
 	}
 
 	private String reflowLongStrings(String input) throws FormatterException {
diff --git a/lib/src/googleJavaFormat/java/com/diffplug/spotless/glue/java/GoogleJavaFormatRemoveUnusedImporterFormatterFunc.java b/lib/src/googleJavaFormat/java/com/diffplug/spotless/glue/java/GoogleJavaFormatRemoveUnusedImporterFormatterFunc.java
index 0073ce9dc9..de21a18795 100644
--- a/lib/src/googleJavaFormat/java/com/diffplug/spotless/glue/java/GoogleJavaFormatRemoveUnusedImporterFormatterFunc.java
+++ b/lib/src/googleJavaFormat/java/com/diffplug/spotless/glue/java/GoogleJavaFormatRemoveUnusedImporterFormatterFunc.java
@@ -15,8 +15,6 @@
  */
 package com.diffplug.spotless.glue.java;
 
-import static com.diffplug.spotless.glue.java.GoogleJavaFormatUtils.fixWindowsBug;
-
 import java.util.Objects;
 
 import javax.annotation.Nonnull;
@@ -37,7 +35,6 @@ public GoogleJavaFormatRemoveUnusedImporterFormatterFunc(@Nonnull String version
 	@Override
 	@Nonnull
 	public String apply(@Nonnull String input) throws Exception {
-		String removedUnused = RemoveUnusedImports.removeUnusedImports(input);
-		return fixWindowsBug(removedUnused, version);
+		return RemoveUnusedImports.removeUnusedImports(input);
 	}
 }
diff --git a/lib/src/googleJavaFormat/java/com/diffplug/spotless/glue/java/GoogleJavaFormatUtils.java b/lib/src/googleJavaFormat/java/com/diffplug/spotless/glue/java/GoogleJavaFormatUtils.java
deleted file mode 100644
index 98f47a6097..0000000000
--- a/lib/src/googleJavaFormat/java/com/diffplug/spotless/glue/java/GoogleJavaFormatUtils.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright 2023 DiffPlug
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.diffplug.spotless.glue.java;
-
-import com.diffplug.spotless.LineEnding;
-
-public class GoogleJavaFormatUtils {
-
-	private static final boolean IS_WINDOWS = LineEnding.PLATFORM_NATIVE.str().equals("\r\n");
-
-	/**
-	 * google-java-format-1.1's removeUnusedImports does *wacky* stuff on Windows.
-	 * The beauty of normalizing all line endings to unix!
-	 */
-	static String fixWindowsBug(String input, String version) {
-		if (IS_WINDOWS && version.equals("1.1")) {
-			int firstImport = input.indexOf("\nimport ");
-			if (firstImport == 0) {
-				return input;
-			} else if (firstImport > 0) {
-				int numToTrim = 0;
-				char prevChar;
-				do {
-					++numToTrim;
-					prevChar = input.charAt(firstImport - numToTrim);
-				} while (Character.isWhitespace(prevChar) && (firstImport - numToTrim) > 0);
-				if (firstImport - numToTrim == 0) {
-					// import was the very first line, and we'd like to maintain a one-line gap
-					++numToTrim;
-				} else if (prevChar == ';' || prevChar == '/') {
-					// import came after either license or a package declaration
-					--numToTrim;
-				}
-				if (numToTrim > 0) {
-					return input.substring(0, firstImport - numToTrim + 2) + input.substring(firstImport + 1);
-				}
-			}
-		}
-		return input;
-	}
-}
diff --git a/lib/src/testGoogleJavaFormat/java/com/diffplug/spotless/glue/java/GoogleJavaFormatUtilsTest.java b/lib/src/testGoogleJavaFormat/java/com/diffplug/spotless/glue/java/GoogleJavaFormatUtilsTest.java
deleted file mode 100644
index a6403c18a0..0000000000
--- a/lib/src/testGoogleJavaFormat/java/com/diffplug/spotless/glue/java/GoogleJavaFormatUtilsTest.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright 2023 DiffPlug
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.diffplug.spotless.glue.java;
-
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
-
-import com.diffplug.common.base.StringPrinter;
-
-public class GoogleJavaFormatUtilsTest {
-
-	@Test
-	void fixWindowsBugForGfj1Point1() {
-		fixWindowsBugTestcase("");
-		fixWindowsBugTestcase(
-				"",
-				"import somepackage;",
-				"");
-		fixWindowsBugTestcase(
-				"import somepackage;",
-				"",
-				"public class SomeClass {}");
-		fixWindowsBugTestcase(
-				"/** Some license */",
-				"import somepackage;",
-				"",
-				"public class SomeClass {}");
-		fixWindowsBugTestcase(
-				"package thispackage;",
-				"",
-				"import somepackage;",
-				"",
-				"public class SomeClass {}");
-		fixWindowsBugTestcase(
-				"/*",
-				" * A License.",
-				" */",
-				"",
-				"package thispackage;",
-				"",
-				"import somepackage;",
-				"",
-				"public class SomeClass {}");
-	}
-
-	private void fixWindowsBugTestcase(String... lines) {
-		String input = StringPrinter.buildStringFromLines(lines);
-		Assertions.assertEquals(input, GoogleJavaFormatUtils.fixWindowsBug(input, "1.1"));
-	}
-}

From c65a0cfc7f5034b5b1cb2d64f968f7dbf6802fcc Mon Sep 17 00:00:00 2001
From: Simon Gamma <github@survive.ch>
Date: Sat, 18 Mar 2023 09:39:57 +0100
Subject: [PATCH 14/15] revert testGlue as it is no longer needed

---
 lib/build.gradle | 13 +------------
 1 file changed, 1 insertion(+), 12 deletions(-)

diff --git a/lib/build.gradle b/lib/build.gradle
index 19bc98f710..e712df9850 100644
--- a/lib/build.gradle
+++ b/lib/build.gradle
@@ -21,21 +21,11 @@ def NEEDS_GLUE = [
 	'cleanthat'
 ]
 for (glue in NEEDS_GLUE) {
-	// main glue
-	def mainGlue = sourceSets.register(glue) {
+	sourceSets.register(glue) {
 		compileClasspath += sourceSets.main.output
 		runtimeClasspath += sourceSets.main.output
 		java {}
 	}
-	// test glue
-	sourceSets.register("test${glue.capitalize()}") {
-		compileClasspath += mainGlue.get().compileClasspath + mainGlue.get().output + sourceSets.test.output
-		runtimeClasspath += mainGlue.get().compileClasspath + mainGlue.get().output + sourceSets.test.output
-		java {}
-	}
-	configurations.named("test${glue.capitalize()}Implementation").configure {
-		extendsFrom(configurations.named("testImplementation").get())
-	}
 }
 
 versionCompatibility {
@@ -82,7 +72,6 @@ dependencies {
 	palantirJavaFormatCompileOnly 'com.palantir.javaformat:palantir-java-format:1.1.0' 	// this version needs to stay compilable against Java 8 for CI Job testNpm
 
 	googleJavaFormatCompileOnly 'com.google.googlejavaformat:google-java-format:1.8' // minimum required version due to api changes before then
-	testGoogleJavaFormatImplementation "com.diffplug.durian:durian-core:$VER_DURIAN"
 
 	// used jackson-based formatters
 	jacksonCompileOnly 'com.fasterxml.jackson.core:jackson-databind:2.14.2'

From 3aea790f1d8ff54854c36ae6e192144ce1626e41 Mon Sep 17 00:00:00 2001
From: Simon Gamma <github@survive.ch>
Date: Mon, 20 Mar 2023 09:38:13 +0100
Subject: [PATCH 15/15] formatting cleanup

---
 .../spotless/glue/java/GoogleJavaFormatFormatterFunc.java       | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/lib/src/googleJavaFormat/java/com/diffplug/spotless/glue/java/GoogleJavaFormatFormatterFunc.java b/lib/src/googleJavaFormat/java/com/diffplug/spotless/glue/java/GoogleJavaFormatFormatterFunc.java
index 97d31da268..f45394979a 100644
--- a/lib/src/googleJavaFormat/java/com/diffplug/spotless/glue/java/GoogleJavaFormatFormatterFunc.java
+++ b/lib/src/googleJavaFormat/java/com/diffplug/spotless/glue/java/GoogleJavaFormatFormatterFunc.java
@@ -35,8 +35,10 @@ public class GoogleJavaFormatFormatterFunc implements FormatterFunc {
 
 	@Nonnull
 	private final String version;
+
 	@Nonnull
 	private final JavaFormatterOptions.Style formatterStyle;
+
 	private final boolean reflowStrings;
 
 	public GoogleJavaFormatFormatterFunc(@Nonnull String version, @Nonnull String style, boolean reflowStrings) {