Skip to content

Optimize Maven configuration on the warm JDK path #1181

Description

@brunoborges

Description:
Reduce Maven configuration overhead on the common warm-JDK path without changing setup-java's existing default behavior.

After the Temurin lazy-loading work, the setup entry point still eagerly imports auth.ts and toolchains.ts. Both modules import xmlbuilder2, and every run creates or updates Maven configuration under ~/.m2, including workflows that primarily use Gradle, sbt, or plain Java. When the requested JDK already exists in the runner tool cache, this local initialization and XML work becomes a meaningful part of the remaining setup duration.

Address these related improvements together:

  1. Avoid loading the XML parser for the default new-file path

    Generate the canonical default settings.xml and a new toolchains.xml using small, deterministic string serializers or templates rather than initializing xmlbuilder2.

    The generated documents must preserve current semantics and formatting requirements, including:

    • Maven settings namespace and schema attributes.
    • interactiveMode=false.
    • Server ID and environment-variable references for credentials.
    • Optional GPG passphrase profile behavior.
    • Maven toolchain version, vendor, ID, and JDK home.
    • Correct XML escaping for all user-controlled values.

    Do not introduce hand-written interpolation that can produce malformed XML. Use a shared XML escaping helper with explicit element-text and attribute handling as required.

  2. Lazy-load xmlbuilder2 only for merge/complex paths

    Existing toolchains.xml files must continue to be merged non-destructively. Dynamically import xmlbuilder2 only when parsing and preserving an existing file or when another configuration shape genuinely requires the full XML library.

    The common hosted-runner case—no existing Maven configuration—should not load xmlbuilder2 at all. Existing custom/non-JDK toolchains, root attributes, namespaces, partially formed entries, and duplicate-removal behavior must remain unchanged on the merge path.

  3. Defer Maven configuration modules until needed and overlap safe work

    Restructure setup orchestration so Maven authentication/settings and toolchain modules are loaded as late as practical. Execute independent filesystem work concurrently where ordering is not required, while preserving deterministic failures.

    In particular:

    • Creating settings.xml and creating a new toolchains.xml may run concurrently when they target separate files.
    • Multiple requested Java versions must still update one toolchains.xml deterministically without lost entries; those merges must remain serialized or be accumulated and written once.
    • Cache restoration may continue concurrently with local configuration as implemented today.
    • If either configuration operation fails, the action must surface the error and await all started work to avoid unhandled rejections.

Acceptance criteria:

  • A warm Temurin run with no existing ~/.m2/toolchains.xml does not load xmlbuilder2.
  • Default generated settings.xml and toolchains.xml are semantically equivalent to the current output.
  • All user-provided XML values are escaped correctly, including &, <, >, quotes, and non-ASCII text where supported.
  • Existing toolchains.xml files retain current non-destructive merge behavior and continue to preserve custom root attributes and non-JDK toolchains.
  • Multi-version and repeated setup-java invocations retain every expected toolchain entry without races or lost updates.
  • overwrite-settings: false, custom settings-path, deprecated aliases, GPG configuration, custom toolchain IDs/vendors, and set-default behavior remain unchanged.
  • Independent settings and toolchain writes overlap only when safe.
  • Unit tests verify that xmlbuilder2 is not loaded on the new-file fast path and is loaded for existing-file merges.
  • Tests compare parsed XML structures, not only raw strings, and cover escaping plus multi-version concurrency.
  • The committed distribution is rebuilt, including all generated chunks.

Performance validation:

Benchmark the current release baseline and proposed implementation on GitHub-hosted Linux, Windows, and macOS runners with a preinstalled Temurin JDK. Capture at least:

  • Temurin tool-cache hit with dependency caching disabled and an empty Maven home.
  • Temurin tool-cache hit with Maven caching enabled.
  • Temurin tool-cache hit with Gradle caching enabled.
  • One Java version and multiple Java versions.
  • Existing toolchains.xml merge as a regression/control scenario.

Use multiple repetitions and report median and p95 setup-step duration. The change should demonstrate a repeatable improvement beyond runner variance for the empty-Maven-home path and must not materially regress the existing-file merge path.

Also report before/after sizes for the eagerly loaded setup entry chunk and confirm whether xmlbuilder2 moved to an on-demand chunk. Total checked-in distribution size is secondary to reducing code parsed and initialized on the common path.

Justification:
Temurin tool-cache hits are among setup-java's highest-volume scenarios. Once JDK downloading and broad distribution/cache imports are removed from that path, eager XML initialization and repeated Maven file generation become prominent avoidable work.

Deferring the full XML implementation while keeping setup-java's established Maven defaults improves warm jobs for Maven, Gradle, sbt, and plain Java users without adding new workflow configuration. Small per-job reductions compound across large CI fleets into faster feedback and lower billed runner time.

Are you willing to submit a PR?
Yes.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions