Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

google-java-format (and removeUnusedImports) broken on JDK 16+ (has workaround) #834

Closed
andrej-urvantsev opened this issue Apr 7, 2021 · 35 comments · Fixed by Together-Java/TJ-Bot#35, ls1intum/Artemis#4173, #1188 or #1224
Labels

Comments

@andrej-urvantsev
Copy link

andrej-urvantsev commented Apr 7, 2021

When running under JDK 16 I get this error message:

Task :spotlessJava FAILED
Step 'google-java-format' found problem in 'src/main/java/se/inoviagroup/v2t/gateway/api/AuthUtils.java':
        ...
Caused by: java.lang.IllegalAccessError: class com.google.googlejavaformat.java.JavaInput (in unnamed module @0x615edab4) cannot access class com.sun.tools.javac.parser.Tokens$TokenKind (in module jdk.compiler) because module jdk.compiler does not export com.sun.tools.javac.parser to unnamed module @0x615edab4
        at com.google.googlejavaformat.java.JavaInput.buildToks(JavaInput.java:349)
        at com.google.googlejavaformat.java.JavaInput.buildToks(JavaInput.java:334)
        at com.google.googlejavaformat.java.JavaInput.<init>(JavaInput.java:276)
        at com.google.googlejavaformat.java.Formatter.getFormatReplacements(Formatter.java:280)
        at com.google.googlejavaformat.java.Formatter.formatSource(Formatter.java:267)
        at com.google.googlejavaformat.java.Formatter.formatSource(Formatter.java:233)
        ... 142 more

EDIT:

EDIT 2 & 3

  • we thought no workaround necessary starting with plugin-gradle 6.5.1 and plugin-maven 2.22.3, but that was incorrect, the workaround is still required
@nedtwigg nedtwigg changed the title Gradle: spotlessApply fails under JDK 16 google-java-format broken on JDK 16+ Apr 7, 2021
@nedtwigg nedtwigg added the bug label Apr 7, 2021
@nedtwigg
Copy link
Member

nedtwigg commented Apr 7, 2021

I think this can be worked-around if we somehow add these flags to the JVM which runs Gradle.

  --add-exports jdk.compiler/com.sun.tools.javac.api=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 \

The deeper fix will be related to #724.

@jmaicher
Copy link

jmaicher commented Apr 12, 2021

This can be done in maven via MAVEN_OPTS or ${maven.projectBasedir}/.mvn/jvm.config, see https://maven.apache.org/configure.html

@dymk
Copy link

dymk commented Apr 13, 2021

@nedtwigg The following can be added to your gradle.properties to work-around the bug:

org.gradle.jvmargs=--add-exports jdk.compiler/com.sun.tools.javac.api=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

@ZacSweers
Copy link
Contributor

ZacSweers commented May 2, 2021

Edit: Nevermind! I had an override of jvmargs in my gradle home that was overridding this

@anuraaga
Copy link
Contributor

I tried playing with the Worker API for running Spotless. As a PoC, I could get GoogleJavaFormatIntegrationTest to pass

https://github.com/diffplug/spotless/compare/main...anuraaga:worker?expand=1

It was nice seeing how so much of the configuration is serializable, presumably to satisfy Gradle cache, which is a requirement for the Worker API. However, not all of it is, for example

https://github.com/diffplug/spotless/compare/main...anuraaga:worker?expand=1#diff-fb99f7a4cb3e09aa538ffb82c60c7119d0eddfb92fd93af98cb6337df1e87476R47
https://github.com/diffplug/spotless/compare/main...anuraaga:worker?expand=1#diff-b8ce946c3dca62f457228d3530c14e442ccdefe8e6619965cd3c2bcebf9e0d94R103

Can any team member skim through that PR to see if it seems feasible at all? If it is I can continue with it but it's quite invasive so want to get a sanity check first.

@nedtwigg
Copy link
Member

nedtwigg commented May 14, 2021

Thanks for the investigation! It is promising. In your draft, there are a few places where a transient String/File path becomes non-transient. These classes are compared for equality based on their serialized representation. By making them non-transient, the remote build cache will no longer work, because task inputs are now keyed on absolute paths.

The root of this problem is LazyForwardingEquality. Pretty much everything in Spotless derives from this. This class allowed us to avoid implementing .equals() and .hashCode() in a lot of places, and it also allowed us to do lazy configuration back in Gradle 2.x, before Gradle had task configuration avoidance.

I think there are two different, but not exactly mutually exclusive paths forward:

  1. Rename LazyForwardingEquality to LazySerializedEquality, and make a new class LazyDelegatedEquality which actually calls .equals() on the state object rather than comparing serialized bytes. This will require writing more boilerplate code, but it allows us to put absolute paths into objects without breaking remote build cache.

  2. Give up on FormatterStep supporting .equals(), and instead have it provide List<File> inputFiles() and Object inputProp(). We would explicitly pass these to Gradle's own up-to-date mechanisms, rather than swallowing them up into our own .equals().

If you are interested in continuing the experiment, open a draft PR and we can continue from there. These improvements are also on the path to properly supporting the Gradle configuration cache.

A248 added a commit to A248/xtomlj that referenced this issue May 21, 2021
* The workaround to make google-java-format work described in
  diffplug/spotless#834 requires raising
  the minimum build requirement to JDK 11.
* Runtime compatibility with JDK 8 is ensured by using the
  '--release' compiler flag.
marcphilipp added a commit to junit-team/junit5 that referenced this issue Jun 4, 2021
connoratrug added a commit to molgenis/molgenis-emx2 that referenced this issue Jun 10, 2021
@nedtwigg nedtwigg changed the title google-java-format broken on JDK 16+ google-java-format (and removeUnusedImports) broken on JDK 16+ (has workaround) Jun 15, 2021
kwvanderlinde added a commit to kwvanderlinde/maptool that referenced this issue Sep 1, 2021
As explained in the [spotless issue tracker](diffplug/spotless#834), there is an outstanding
issue with the google formatter depending on JDK internals. We add the flags listed there to avoid module errors when
running spotless.

After upgrading and rerunning `spotlessApply`, several stray semicolons became apparent and have now been removed.
illuminator3 added a commit to Together-Java/TJ-Bot that referenced this issue Sep 8, 2021
Tais993 added a commit to Together-Java/TJ-Bot that referenced this issue Sep 8, 2021
* Bump JDA version to 324 (#31)

Updates JDA (they forgot something with slash-commands, has been added now)

* Add spotless integration

This hopefully makes formatting more consistent. The Eclipse XML style
was chosen as it is understood by Eclipse, VSC (JDT), Spotless and
mostly by IntelliJ.

* Make gradelew executable

* Add "Remove unused imports" setting to spotless

Co-authored-by: Marko Radosavljević <marko@radosavljevic.dev>

* Remove unused imports to fix diffplug/spotless#834 (#35)

Co-authored-by: I-Al-Istannen <i-al-istannen@users.noreply.github.com>
Co-authored-by: Marko Radosavljević <marko@radosavljevic.dev>
Co-authored-by: Jonas <jnhrd254@gmail.com>
@ascopes
Copy link
Contributor

ascopes commented Sep 12, 2021

@nedtwigg

I think this can be worked-around if we somehow add these flags to the JVM which runs Gradle.

It is worth being wary of doing this, since passing these flags will cause javac for JDK 1.8 to fail, as the flags are unsupported.

nakamura-to added a commit to domaframework/doma-it that referenced this issue Sep 13, 2021
zachgk added a commit to deepjavalibrary/djl-serving that referenced this issue Aug 2, 2022
J-N-K added a commit to J-N-K/openhab-core that referenced this issue Aug 19, 2022
See diffplug/spotless#834

Signed-off-by: Jan N. Klug <github@klug.nrw>
nedtwigg added a commit to mernst/spotless that referenced this issue Sep 14, 2022
b3z added a commit to trintel/trintel that referenced this issue Oct 23, 2022
J-N-K added a commit to J-N-K/openhab-core that referenced this issue Dec 8, 2022
See diffplug/spotless#834

Signed-off-by: Jan N. Klug <github@klug.nrw>
J-N-K added a commit to J-N-K/openhab-core that referenced this issue Dec 16, 2022
See diffplug/spotless#834

Signed-off-by: Jan N. Klug <github@klug.nrw>
J-N-K added a commit to J-N-K/openhab-core that referenced this issue Dec 19, 2022
See diffplug/spotless#834

Signed-off-by: Jan N. Klug <github@klug.nrw>
wborn pushed a commit to openhab/openhab-core that referenced this issue Dec 19, 2022
* Raise source level to Java 17 (except for model classes)
* Remove Nashorn script engine
* Upgrade spotless and add jvm options  
  See diffplug/spotless#834
* Add suppression for findBugs false positive error
* Upgrade xtext to 2.29.0
* Adjust JNA
* Resolve itests

Signed-off-by: Jan N. Klug <github@klug.nrw>
eduardz1 added a commit to eduardz1/Jmail that referenced this issue Dec 22, 2022
runningcode pushed a commit to runningcode/junit5 that referenced this issue Feb 15, 2023
splatch pushed a commit to ConnectorIO/copybara-hab-core that referenced this issue Jul 12, 2023
* Raise source level to Java 17 (except for model classes)
* Remove Nashorn script engine
* Upgrade spotless and add jvm options
  See diffplug/spotless#834
* Add suppression for findBugs false positive error
* Upgrade xtext to 2.29.0
* Adjust JNA
* Resolve itests

Signed-off-by: Jan N. Klug <github@klug.nrw>
GitOrigin-RevId: 41ba3ff
@poojaverma009
Copy link

Is there any way to resolve this without updating gradle.proerties file with below
org.gradle.jvmargs=--add-exports jdk.compiler/com.sun.tools.javac.api=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

@tisonkun
Copy link
Contributor

@poojaverma009 upgrade to the latest Spotless. It's resolved.

@poojaverma009
Copy link

I am trying to update my project from jdk version 11 to 17 but I am getting below error
Step 'removeUnusedImports' found problem in 'functional-tests/src/main/java/com/comp/atlas/oyo/upgrade/configuration/TesterConfiguration.java':
null
java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at com.diffplug.spotless.java.GoogleJavaFormatStep$State.lambda$constructRemoveUnusedFunction$3(GoogleJavaFormatStep.java:190)
at com.diffplug.spotless.java.GoogleJavaFormatStep$State.lambda$createRemoveUnusedImportsOnly$1(GoogleJavaFormatStep.java:167)
at com.diffplug.spotless.FormatterFunc.apply(FormatterFunc.java:32)
at com.diffplug.spotless.FormatterStepImpl$Standard.format(FormatterStepImpl.java:78)
at com.diffplug.spotless.FormatterStep$Strict.format(FormatterStep.java:76)
at com.diffplug.spotless.Formatter.compute(Formatter.java:230)
at com.diffplug.spotless.PaddedCell.calculateDirtyState(PaddedCell.java:201)
at com.diffplug.spotless.PaddedCell.calculateDirtyState(PaddedCell.java:188)
at com.diffplug.gradle.spotless.SpotlessTaskImpl.processInputFile(SpotlessTaskImpl.java:71)
at com.diffplug.gradle.spotless.SpotlessTaskImpl.performAction(SpotlessTaskImpl.java:57)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:125)
at org.gradle.api.internal.project.taskfactory.IncrementalInputsTaskAction.doExecute(IncrementalInputsTaskAction.java:32)
at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:51)
at org.gradle.api.internal.project.taskfactory.AbstractIncrementalTaskAction.execute(AbstractIncrementalTaskAction.java:25)
at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:29)

@tisonkun
Copy link
Contributor

@poojaverma009 which version of spotless do you use?

@poojaverma009
Copy link

spotlessVersion = '5.14.3'

@tisonkun
Copy link
Contributor

tisonkun commented Nov 27, 2023

This is fixed by #1224 and #1228 so use a version >= 6.7.1 should work.

This is what I mean by:

@poojaverma009 upgrade to the latest Spotless. It's resolved.

@poojaverma009
Copy link

Thanks
It worked

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