Skip to content

Keep imports used by Markdown doc comments in removeUnusedImports - #3163

Open
1AbdullahButt wants to merge 2 commits into
diffplug:mainfrom
1AbdullahButt:fix/3161-markdown-javadoc-imports
Open

1AbdullahButt wants to merge 2 commits into
diffplug:mainfrom
1AbdullahButt:fix/3161-markdown-javadoc-imports

Conversation

@1AbdullahButt

@1AbdullahButt 1AbdullahButt commented Nov 6, 2026 •

Copy link
Copy Markdown

Fixes #3161

Cause

On JDK 23+, javac turns Markdown doc comments (///) into doc trees with a DocCommentTreeTransformer from the jdk.internal.md module. JavacTrees.initDocCommentTreeTransformer() finds it with ServiceLoader.load(...), which uses the thread's context class loader. jdk.internal.md (like jdk.compiler) is defined to the JDK's app class loader. Gradle and Maven run Spotless with a context class loader whose parent chain doesn't include the app loader, so the lookup finds nothing and javac quietly uses its identity transformer. google-java-format's RemoveUnusedImports then never sees the [ArrayList#add] style links, so it drops the imports they use.

The fix is in Spotless, not google-java-format: GJF just calls JavacTrees.getDocCommentTree, which works when the context class loader is the app loader (for example, the GJF CLI).

Fix

A small glue helper, GoogleJavaFormatUnusedImports, calls RemoveUnusedImports.removeUnusedImports with javac's own class loader (DocTrees.class.getClassLoader()) as the context class loader, and restores the original loader afterwards. It's used by both removeUnusedImports() and googleJavaFormat(), since the latter also runs RemoveUnusedImports. On JDKs before 23 there is no provider, so nothing changes.

Tests

  • New RemoveUnusedImportsStep_withGoogleJavaFormatTest.markdownJavadoc() (JDK 23+) with the MarkdownJavadoc*.test resources. It sets the context class loader to the platform class loader to simulate the build tools.
  • Ran locally on Temurin 25.0.5. Without the fix the new test fails with the output from the issue (all three used imports removed). With the fix, RemoveUnusedImportsStep_withGoogleJavaFormatTest and GoogleJavaFormatStepTest all pass, and :lib:spotlessCheck and :testlib:spotlessCheck pass.
  • I didn't run the full test suite or an end-to-end Gradle/Maven plugin build.

CHANGES.md, plugin-gradle/CHANGES.md and plugin-maven/CHANGES.md are updated under [Unreleased].

This change was written with Claude Code (AI).

🤖 Generated with Claude Code

1AbdullahButt and others added 2 commits November 7, 2026 03:53
On JDK 23+, javac parses Markdown doc comments (`///`) with a
transformer from the jdk.internal.md module, which it finds with
ServiceLoader on the thread's context class loader. Gradle and Maven
run Spotless with a context class loader that cannot see that module,
so javac fell back to treating the comments as plain text, and
google-java-format removed imports used only by their links.

Run google-java-format's RemoveUnusedImports with javac's own class
loader as the context class loader.

Fixes diffplug#3161

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…adoc-imports

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

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.

removeUnusedImports() does not parse Markdown Javadoc

1 participant