google-java-format
google-java-format copied to clipboard
Intellij plugin seems to stop working when Java 14/15 features are used
I use the latest google-java-format Intellij plugin based on google-java-format 1.9. As I understand it, this version should support Java 14/15 features like switch expressions and text blocks. In our case if any of the mentioned language features are used formatting stops working.
Just wanted to ask whether this may be a bug in my setup or if you're seeing the same problems?
Intellij IDEA Version: Ultimate Edition 2020.2.3 (Build #IU-202.7660.26, built on October 6, 2020)
Operating System: Ubuntu 20.04.1 LTS
Here is a small example:
public class FormatTest {
enum Test {
A, B
}
public static void main(String[] args) {
String foo = "This should not be here";
Test t = Test.A;
String foobar = switch(t) {
case A -> "foobar";
case B -> "barfoo";
};
String xyz = """
""";
}
}
When I try to format this inside the IDE nothing happens. It shows that it's reformatting the code but the formatting doesn't change.There is no error as far as I can see.
However, formatting it with google-java-format-1.9-all-deps.jar it outputs correctly:
public class FormatTest {
enum Test {
A,
B
}
public static void main(String[] args) {
String foo = "This should not be here";
Test t = Test.A;
String foobar =
switch (t) {
case A -> "foobar";
case B -> "barfoo";
};
String xyz = """
""";
}
}
Any help concerning this issue would be very much appreciated! Thanks for your great work!
@plumpy seems like #517 didn't fix that?
Can report the same (using google-java-format plugin 1.9.0.0 and intellij 2020.2).
I think this is because the default Intellij runtime still uses jdk 11 (at least for 2020.2 and lower). Based on that, the formatter will not load the Java14InputAstVisitor (code ref).
After manually switching my intellij runtime to one that uses jdk 15 (following this guide), the formatter worked as expected with java 14 language features. However this is not recommended as there are minor differences in the intellij runtime.
Thank you @fawind, worked fine here! :)
@fawind Tried following the guide you mentioned, but the Choose Runtime approach isn't giving me any success. Did you follow the steps for manually changing your runtime version, or if not, what version of the runtime did you use? 🤔
As an alternative workaround to changing IntelliJ's runtime JDK version, we can also use IntelliJ's External Tool feature to run the formatter as an external command using a different JDK:
Arguments:
-Xmx256m
-XX:TieredStopAtLevel=1
--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
-jar <download-the-latest-all-deps-jar>/google-java-format-1.10.0-all-deps.jar
--replace $FilePath$
In the above screenshot, it's configured to use the same JDK as the one used to compile the project to run the formatter ($JDKPath$), added -XX:TieredStopAtLevel=1 too as it seems to make it run quicker for me, since the format process will be short lived.
Then under Keymap in IntelliJ's main settings, bind it to a keyboard shortcut to invoke it.
I don't know if this is a stupid question but why should the version of JVM running the formatter be assumed to be the same version as the code it's formatting? Is there something in Java14InputAstVisitor that can't run on Java 11? Even if it was behind a flag I don't understand why it shouldn't just load the rules. IntelliJ itself obviously doesn't have this problem.
As an alternative workaround to changing IntelliJ's runtime JDK version, we can also use IntelliJ's External Tool feature to run the formatter as an external command using a different JDK:
![]()
Arguments:
-Xmx256m -XX:TieredStopAtLevel=1 --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 -jar <download-the-latest-all-deps-jar>/google-java-format-1.10.0-all-deps.jar --replace $FilePath$In the above screenshot, it's configured to use the same JDK as the one used to compile the project to run the formatter (
$JDKPath$), added-XX:TieredStopAtLevel=1too as it seems to make it run quicker for me, since the format process will be short lived.Then under
Keymapin IntelliJ's main settings, bind it to a keyboard shortcut to invoke it.
Thanks for the external tools, working great.
the same problem occurs if you run the gradle spotless plugin and configure google java format with java 17 source code and gradle using java 11.
@bjrke for some reason intellij does not by default use the project JVM for the build tool; you can set it here https://www.jetbrains.com/help/idea/gradle-settings.html#gradle_jvm
@chadselph I think it's different - for me gradle builds works fine, it's when you try to format code using built-in formatter, then it does not work(probably because IDEA is still on java 11)
In our fork of google-java-format, we solved this with the workaround of bootstrapping a new JVM to run the formatter in (code example). In the Intellij plugin, we retrieve the path of the project JDK and and use this JDK to run the formatter main class. This allows us to also set the additional --add-export flags that are now required at runtime for Java 16+ (ref).
The downside is that it adds some latency to each format action but this has been tolerable so far and unblocks projects that want to use newer language features.
Might be worth considering doing something similar here. Happy to contribute this back if wanted!
Apparently this is tied to the runtime version of IntelliJ itself. According to this table starting with version 2022.2 IntelliJ uses JDK 17. Therefore, once you upgrade to that version or newer, I think this issue is resolved?
Note that you'll have to update IntelliJ's configuration to add custom VM options; see #787
This should be fixed if you use the newest version of the plugin (1.16.0.0) with Intellij 2022.3.