Skip to content

fix: support import module in removeUnusedImports (GJF 1.30.0) - #3008

Merged
nedtwigg merged 6 commits into
diffplug:mainfrom
arimu1:fix/2890-module-import-remove-unused
Aug 16, 2026
Merged

fix: support import module in removeUnusedImports (GJF 1.30.0)#3008
nedtwigg merged 6 commits into
diffplug:mainfrom
arimu1:fix/2890-module-import-remove-unused

Conversation

@arimu1

@arimu1 arimu1 commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Problem

java { removeUnusedImports() } / <removeUnusedImports/> fails on sources that use Java's import module (JEP 511), e.g.:

import module java.base;

class ModuleImportTest {
  void test() {
    UUID.randomUUID();
  }
}

with:

LINE_UNDEFINED removeUnusedImports(java.lang.IllegalArgumentException)
object of type com.sun.tools.javac.tree.JCTree$JCModuleImport is not an instance of com.sun.tools.javac.tree.JCTree$JCImport

Root cause: default google-java-format was still 1.28.0. Module-import support landed in google-java-format 1.30.0 (google/google-java-format#1213 / #1297), which skips JCModuleImport in RemoveUnusedImports instead of casting every import tree to JCImport.

Fixes #2890

Solution

  • Default google-java-format remains 1.28.0 on JVM 17 (1.30.0 references JCAnyPattern, which only exists in JDK 21+ javac)
  • Default bumps to 1.30.0 on JVM 21+
  • Require at least 1.30.0 on JVM 25+ (Jvm.Support.addMin) for import module support
  • Align gradle/libs.versions.toml compile coordinate with 1.30.0 (compile-only adapter)
  • Regression tests for module imports (JDK 25+) and the new JVM 25 minimum

Users who pin an older GJF version on JVM 25 get a clear lint instead of a ClassCastException mid-format.

Testing

# JDK 17 — default stays 1.28.0 (1.30.0 would NoClassDefFoundError on JCAnyPattern)
JAVA_HOME=…/jbr-17 ./gradlew :testlib:test \
  --tests 'com.diffplug.spotless.java.RemoveUnusedImportsStep_withGoogleJavaFormatTest' \
  --tests 'com.diffplug.spotless.java.GoogleJavaFormatStepTest'
# 16 tests, 4 skipped — all green

# JDK 21 — default is 1.30.0
JAVA_HOME=…/jdk-21 ./gradlew :testlib:test \
  --tests 'com.diffplug.spotless.java.RemoveUnusedImportsStep_withGoogleJavaFormatTest' \
  --tests 'com.diffplug.spotless.java.GoogleJavaFormatStepTest'
# 16 tests, 4 skipped — all green

# JDK 25
JAVA_HOME=…/jdk-25 ./gradlew :testlib:test \
  --tests 'com.diffplug.spotless.java.RemoveUnusedImportsStep_withGoogleJavaFormatTest' \
  --tests 'com.diffplug.spotless.java.GoogleJavaFormatStepTest'
# moduleImports + versionBelowMinOnJava25IsNotAllowed green

Platform: macOS aarch64, JBR 17.0.14 + Temurin 21.0.12 + Temurin 25.0.4

Checklist

arimu1 and others added 4 commits August 1, 2026 14:29
Bump default google-java-format 1.28.0 -> 1.30.0 (first release that
handles JCModuleImport) and require at least 1.30.0 on JVM 25+.

Fixes diffplug#2890
…t-remove-unused

# Conflicts:
#	CHANGES.md
#	plugin-gradle/CHANGES.md
#	plugin-maven/CHANGES.md
…t-remove-unused

# Conflicts:
#	plugin-gradle/CHANGES.md
#	plugin-maven/CHANGES.md
@nedtwigg

Copy link
Copy Markdown
Member

Seems like we're good on Java 21+ but this introduces a problem for Java 17. Not sure if it's a code problem or a tests problem.

google-java-format 1.30.0 references JCAnyPattern (JDK 21+ javac only),
so it must not be the default on JVM 17. Restore 1.28.0 for JDK 17 while
keeping 1.30.0 default on JVM 21+ and addMin(25, 1.30.0) for import module.
@arimu1
arimu1 force-pushed the fix/2890-module-import-remove-unused branch from 6abba06 to 7bd31e1 Compare August 16, 2026 09:24
@arimu1

arimu1 commented Aug 16, 2026

Copy link
Copy Markdown
Contributor Author

@nedtwigg This was a code problem, not a test problem.

The JDK 17 CI failures (NoClassDefFoundError: com/sun/tools/javac/tree/JCTree$JCAnyPattern) came from making google-java-format 1.30.0 the default on JVM 17. GJF 1.30.0 references JCAnyPattern, which only exists in JDK 21+ javac — so loading it on JDK 17 fails before any test assertion runs.

Fixed in 7bd31e1 by restoring the JVM-split defaults:

  • JVM 17: default stays 1.28.0 (last GJF version that runs on JDK 17)
  • JVM 21+: default 1.30.0
  • JVM 25+: still requires ≥ 1.30.0 via addMin(25, "1.30.0") for import module support

Verified locally on JBR 17 and Temurin 21 — GoogleJavaFormatStepTest and RemoveUnusedImportsStep_withGoogleJavaFormatTest pass on both.

…t-remove-unused

# Conflicts:
#	CHANGES.md
#	plugin-gradle/CHANGES.md
#	plugin-maven/CHANGES.md
@nedtwigg
nedtwigg merged commit 8e6812a into diffplug:main Aug 16, 2026
19 checks passed
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.

java.removeUnusedImports does not handle import module correctly

2 participants