1

I am upgrading my Spring Boot app to use Spring 3+ and Java 17. However, I'm now getting an error when trying to apply spotless and to do with removeUnusedImports feature.

This issue is similar to what has been reported here: github.com/diffplug/spotless/issues/923

I have tried a few things, such as adding this:

-Xmx4096m
--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED
--add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED
--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED
--add-exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED
--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED
--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED

To my IntelliJ VM Options as per here: https://github.com/google/google-java-format#intellij-jre-config

I also tried to add this directly to maven through typing the below on my git terminal:

export MAVEN_OPTS="-Xmx4096m --add-exports=jdk.compiler/com.sun.tools.javac.ap
i=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED --
add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED --add-exports=jdk.
compiler/com.sun.tools.javac.parser=ALL-UNNAMED --add-exports=jdk.compiler/com.s
un.tools.javac.tree=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.u
$ git config --global credential.helper "cache --timeout=3600"

However, the issue still persists.

  <spotless-plugin.version>2.34.0</spotless-plugin.version>
  <spotless-eclipse.version>4.18.0</spotless-eclipse.version>
  <spring-boot.version>3.1.3</spring-boot.version>
            <plugin>
                <groupId>com.diffplug.spotless</groupId>
                <artifactId>spotless-maven-plugin</artifactId>
                <version>${spotless-plugin.version}</version>
                <configuration>
                    <formats>
                        <!-- you can define as many formats as you want, each is independent -->
                        <format>
                            <!-- define the files to apply to -->
                            <includes>
                                <include>*.java</include>
                                <include>*.md</include>
                            </includes>
                            <!-- define the steps to apply to those files -->
                            <trimTrailingWhitespace/>
                            <endWithNewline/>
                            <indent>
                                <tabs>true</tabs>
                                <spacesPerTab>4</spacesPerTab>
                            </indent>
                        </format>
                    </formats>
                    <!-- define a language-specific format -->
                    <java>
                        <!-- no need to specify files, inferred automatically, but you can if you want -->

                         <removeUnusedImports/> <!-- self-explanatory -->

                        <!-- apply a specific flavor of google-java-format and reflow long strings -->
                        <eclipse>
                            <version>${spotless-eclipse.version}</version> <!-- optional -->
                            <file>${project.basedir}/eclipse-formatter.xml</file> <!-- optional -->
                        </eclipse>
                    </java>
                </configuration>
            </plugin>

This is the exact error here:

[INFO] Spotless.Format is keeping 1 files clean - 0 were changed to be clean, 1 were already clean, 0 were skipped because caching determined they were already clean
[ERROR] Step 'removeUnusedImports' found problem in 'src\test\java\com\myproject\amlar\client\DBClient.java':
null
java.lang.reflect.InvocationTargetException
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
    at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke (Method.java:566)
    at com.diffplug.spotless.java.GoogleJavaFormatStep$State.lambda$constructRemoveUnusedFunction$4 (GoogleJavaFormatStep.java:211)
Caused by: com.google.googlejavaformat.java.FormatterException: 37:25: error: unclosed string literal
    at com.google.googlejavaformat.java.FormatterException.fromJavacDiagnostics (FormatterException.java:51)
    at com.google.googlejavaformat.java.RemoveUnusedImports.parse (RemoveUnusedImports.java:262)
    at com.google.googlejavaformat.java.RemoveUnusedImports.removeUnusedImports (RemoveUnusedImports.java:219)
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
    at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke (Method.java:566)
    at com.diffplug.spotless.java.GoogleJavaFormatStep$State.lambda$constructRemoveUnusedFunction$4 (GoogleJavaFormatStep.java:211)
    at com.diffplug.spotless.java.GoogleJavaFormatStep$State.lambda$createRemoveUnusedImportsOnly$2 (GoogleJavaFormatStep.java:188)
    at com.diffplug.spotless.FormatterFunc.apply (FormatterFunc.java:32)
    at com.diffplug.spotless.FormatterStepImpl$Standard.format (FormatterStepImpl.java:82)
    at com.diffplug.spotless.FormatterStep$Strict.format (FormatterStep.java:88)
    at com.diffplug.spotless.Formatter.compute (Formatter.java:246)
    at com.diffplug.spotless.PaddedCell.calculateDirtyState (PaddedCell.java:203)
    at com.diffplug.spotless.PaddedCell.calculateDirtyState (PaddedCell.java:190)
    at com.diffplug.spotless.maven.SpotlessApplyMojo.process (SpotlessApplyMojo.java:48)
    at com.diffplug.spotless.maven.AbstractSpotlessMojo.execute (AbstractSpotlessMojo.java:225)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:137)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:210)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:156)
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  2.439 s
[INFO] Finished at: 2023-09-18T12:43:17+01:00

Thank you.

14
  • UnclosedStringLiteral -> hasn't got much to do with import statements. Have you checked your DBClient.java class?
    – Stultuske
    Commented Sep 18, 2023 at 11:48
  • Can you add a minimal reproducible example containing the smallest amount of code needed to reproduce this problem?
    – user8681
    Commented Sep 18, 2023 at 11:49
  • There are some people who have already reported this error github.com/diffplug/spotless/issues/923 Commented Sep 18, 2023 at 11:50
  • 1
    The linked github issue suggests there is a bug. All software has bugs. This one seems odd, why aren't you removing unused imports before you commit your code? That seems like a pre-commit check to me. Or something to catch in code review. Commented Sep 18, 2023 at 11:57
  • 1
    I tried updating spotless before raising the question, but got this other error, which happens even without the removeUnusedImports tag, so I kept the older version: [ERROR] Failed to execute goal com.diffplug.spotless:spotless-maven-plugin:2.36.0:apply (default-cli) on project aml-ar-api-automation: Execution default-cli of goal com.diffplug.spotl ess:spotless-maven-plugin:2.36.0:apply failed.: NullPointerException -> [Help 1] Commented Sep 18, 2023 at 13:02

2 Answers 2

1

I faced a similar issue and tried the workaround you also mentioned. Nothing helped, I also tried removing removeUnusedImports from pom.xml (it didn't work).

Finally

  1. Added the code block:
  <removeUnusedImports>
     <engine>google-java-format</engine>    <!-- optional. Defaults to `google-java-format`. Can be switched to `cleanthat-javaparser-unnecessaryimport` (e.g. to process JDK17 source files with a JDK8+ Runtime) -->
  </removeUnusedImports> 
  1. Then the error message changed, So I finally shifted to the latest version of Spotless and checked various googleJavaFormat versions with it. Finally, the below combination worked for me.
    <plugin>
                <groupId>com.diffplug.spotless</groupId>
                <artifactId>spotless-maven-plugin</artifactId>
                <version>2.43.0</version>
                <configuration>
                    <ratchetFrom>origin/master</ratchetFrom>
                    <java>
                        <includes>
                            <include>src/main/java/**/*.java</include>
                            <include>src/test/java/**/*.java</include>
                        </includes>

                        <importOrder>  <!-- or a custom ordering -->
                            <order>java,javax,org,com,com.diffplug,</order>  <!-- or use <file>${basedir}/eclipse.importorder</file> -->
                            <!-- You probably want an empty string at the end - all of the
                                 imports you didn't specify explicitly will go there. -->
                        </importOrder>

                        <removeUnusedImports>
                            <engine>google-java-format</engine>    <!-- optional. Defaults to `google-java-format`. Can be switched to `cleanthat-javaparser-unnecessaryimport` (e.g. to process JDK17 source files with a JDK8+ Runtime) -->
                        </removeUnusedImports>  <!-- self-explanatory -->

                        <googleJavaFormat>
                            <version>1.19.2</version>
                            <style>GOOGLE</style>
                        </googleJavaFormat>
                    </java>
                </configuration>
    </plugin>

What I feel is that in IntelliJ, the engine isn't detected automatically for removeUnusedImports hence it throws an error. Now that we have mentioned the engine explicitly it works well.

1
  • Thank you for your answer. It made me revisit the issue. Your solution didn't fully work for our case as we're not using the google formatter, but I noticed that reaadding the <removeUnusedImport/> piece plus removing the explicit version for the eclipse jdt seem to work okay. I could however update Spotless only up to version 2.34.0 as after I get some other errors which seem to do with okhttp3. Commented Jul 22 at 10:59
0

It seems removing the explicit version for the eclipse formatter and readding the <removeUnusedImport> piece works for <spotless-plugin.version>2.34.0</spotless-plugin.version>.

PS: I wasn't able to update Spotless above that as from 2.35.0 onwards, I get this error:

[ERROR] Failed to execute goal com.diffplug.spotless:spotless-maven-plugin:2.35.0:apply (default-cli) on project aml-ar-api-automation: Execution default-cli of goal com.diffplug.spotless:spotless-maven-plugin:2.35.0:apply failed: okhttp3.internal.http2.StreamResetException: stream was reset: NO_ERROR -> [Help 1]

Not the answer you're looking for? Browse other questions tagged or ask your own question.