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

Bootstrap new jvm for running formatter with flags #562

Merged
merged 11 commits into from
Nov 3, 2021
Merged

Conversation

fawind
Copy link
Contributor

@fawind fawind commented Oct 27, 2021

Before this PR

There are two issue with running the formatter targeting newer Java versions:

  1. Intellij runs plugins using its custom JDK 11 which results in the intellij plugin not being able to format files containing newer language features.
  2. Starting with Java 16, the JVM running the formatter has to be run with additional --add-export flags due to JEP 396 (ref).

After this PR

As a workaround to both problems we bootstrap a new JVM in which we run the formatter. This allows us to specify the additional jvm flags without having to set them on the main JVM process and to run the formatter with a newer JDK than the one provided by Intellij

FLUPS:

  • Improve performance for spotless-gradle integration - For now we just updated the Intellij plugin.
  • Enable bootstrapping intellij formatter for projects > Java 11

==COMMIT_MSG==
Bootstrap new jvm for running formatter with flags
==COMMIT_MSG==

@fawind fawind changed the title WIP: Bootstrap new jvm for running formatter with flags Bootstrap new jvm for running formatter with flags Oct 29, 2021
@@ -37,7 +37,7 @@ private PalantirJavaFormatStep() {}
/** Creates a step which formats everything - code, import order, and unused imports. */
public static FormatterStep create(Configuration palantirJavaFormat, JavaFormatExtension extension) {
ensureImplementationNotDirectlyLoadable();
Supplier<FormatterService> memoizedService = extension::serviceLoad;
Supplier<FormatterService> memoizedService = extension::loadFormatterService;
return FormatterStep.createLazy(
NAME, () -> new State(palantirJavaFormat.getFiles(), memoizedService), State::createFormat);
Copy link
Contributor Author

@fawind fawind Oct 29, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The gradle integration is very slow because spotless invokes one formatter command per file which will now start a new jvm each. On a medium-sized project (205 java file), formatting all files took ~2 mins. Fortunately files are cached and not reformatted if they don't change.

One solution would be to keep a JVM hot and use this for all formatter invocations. However I would do this as a follow up PR to keep this one smaller. For now, the slow bootstrapping formatter is only used when using Java 16+ (can also make it opt-in to start with).

Copy link
Contributor Author

@fawind fawind Nov 3, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are running into similar problems with spotless in gradle-baseline (see diffplug/spotless#834). As this plugin is more integrated with Gradle, its not super easy to bootstrap this part to a JVM. While waiting for an upstream fix, we will probably use this workaround and add the export flags to the gradle.properties for the first rollout of Java 17. Based on that, I'll let the pjf gradle integration use the old codepath and not use a bootstrapped jvm.

@fawind
Copy link
Contributor Author

fawind commented Oct 29, 2021

Let me try deving with the intellij Plugin for a day to see how the latency is.

List<URL> implementationUrls =
getImplementationUrls(cacheKey.implementationClassPath, cacheKey.useBundledImplementation);
Path jdkPath = getJdkPath(cacheKey.project);
Integer jdkVersion = getSdkVersion(cacheKey.project);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about using the "same-jvm" formatter for older jvm version but given that in intellij we need the bootstrapping formatter for all projects using Java 12+ it would rather just have one code path.

Also the additional overhead shouldn't be as noticeable in intellij as the usual workflow is to just re-format the current file instead of all files in the project.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about using the "same-jvm" formatter for older jvm version but given that in intellij we need the bootstrapping formatter for all projects using Java 12+ it would rather just have one code path.

It might be helpful to avoid introducing risk/bugs for existing workflows, to begin with anyhow

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking that ideally we would already use the bootstrapping formatter for Java 15, which basically includes all internal users at this point.

But given that the formatter didn't support new language features on Java 15 so far, we can start defensively with only enabling the bootstrapping formatter for Java 16+ where it would fail to run. Can enable it for Java 15 in a FLUP PR once this has soaked for a while.

@fawind fawind marked this pull request as ready for review October 29, 2021 13:28
@fawind
Copy link
Contributor Author

fawind commented Nov 3, 2021

Reverted the changes to the gradle plugin and fixed the case where we would surface errors of the formatter failing on invalid java syntax to the Intellij UI (we now silently ignore these).

Will cut a release now. This effectively just changed the codepath of the Intellij Plugin when using Java 16+ as project SDK.

@fawind fawind merged commit 2074d63 into develop Nov 3, 2021
@fawind fawind deleted the fw/bootstrap-jre branch November 3, 2021 15:18
@svc-autorelease
Copy link
Collaborator

Released 2.4.0

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

Successfully merging this pull request may close these issues.

3 participants