Skip to content
Use this GitHub action with your project
Add this Action to an existing workflow or create a new one
View on Marketplace

Repository files navigation

Setup Java

Basic validation Validate Java e2e Validate cache

Set up Java for GitHub Actions workflows. setup-java installs a requested Java distribution, adds it to PATH, configures JAVA_HOME, and can optionally cache build dependencies for Apache Maven, Gradle, and sbt; generate Maven publishing configuration, verify JDK package signatures, manage multiple JDKs, and manage Maven toolchains.

steps:
  - uses: actions/checkout@v7
  - uses: actions/setup-java@v6
    with:
      distribution: temurin
      java-version: '25'
  - run: java --version

Note

V6 is still in development on the main branch and is not yet recommended for production workflows. To use it, you must explicitly reference the main branch in your workflow, as in

- uses: actions/setup-java@main

For production workflows, it is recommended to use the latest stable release v5.

Contents

What it does

  • Downloads and installs Java from a supported distribution.
  • Uses a requested Java version, a version file, or the latest stable release alias.
  • Extracts and caches a custom JDK archive from a local file.
  • Configures Maven settings.xml, Maven Toolchains, Maven GPG signing inputs, and environment-variable based credentials for publishing workflows.
  • Registers Java problem matchers for compiler diagnostics and uncaught exceptions.
  • Caches dependencies for Maven, Gradle, and sbt.
  • Verifies downloaded archive checksums when a distribution publishes authoritative checksums.
  • Optionally verifies package signatures for supported distributions.

setup-java works with Java, Scala, Kotlin, Gradle, Maven, and sbt projects.

What's new

V6 (in development)

  • Migrated the action implementation to ESM to support the latest @actions/* packages.
  • Renamed environment-variable-name inputs so they are not mistaken for secret values:
    • server-username -> server-username-env-var
    • server-password -> server-password-env-var
    • gpg-passphrase -> gpg-passphrase-env-var
  • Deprecated aliases still work, but emit warnings.
  • Maven GPG passphrases are now passed through gpg.passphraseEnvName instead of a deprecated gpg.passphrase server entry in settings.xml. This requires maven-gpg-plugin 3.2.0 or newer. See GPG.
  • Legacy AdoptOpenJDK distributions were removed. Use temurin instead of adopt or adopt-hotspot, and semeru instead of adopt-openj9.

V5

Usage

Install Eclipse Temurin

steps:
  - uses: actions/checkout@v7
  - uses: actions/setup-java@v6
    with:
      distribution: temurin
      java-version: '25'
  - run: java --version

Install Microsoft Build of OpenJDK

steps:
  - uses: actions/checkout@v7
  - uses: actions/setup-java@v6
    with:
      distribution: microsoft
      java-version: '25'
  - run: java --version

Read the version from a file

steps:
  - uses: actions/checkout@v7
  - uses: actions/setup-java@v6
    with:
      distribution: temurin
      java-version-file: .java-version
  - run: java --version

Supported version files are .java-version, .tool-versions, and .sdkmanrc. A .sdkmanrc file can also provide the distribution when it contains a recognized suffix, such as java=21.0.5-tem.

Use the newest stable Java

steps:
  - uses: actions/checkout@v7
  - uses: actions/setup-java@v6
    with:
      distribution: temurin
      java-version: latest
  - run: java --version

latest always resolves from the distribution's remote metadata and uses the newest stable GA release. It is not supported with java-version-file, early-access versions, or distribution: jdkfile.

Inputs

Input Description Default
java-version Java version to install. Supports whole versions, semver ranges, early-access versions, and latest. Required unless java-version-file is set.
java-version-file Path to .java-version, .tool-versions, or .sdkmanrc. Used when java-version is not set.
distribution Java distribution keyword. Values are case-sensitive and must match one of the supported keywords below. Required unless java-version-file points to .sdkmanrc with a recognized distribution suffix.
java-package Package variant such as jdk, jre, jdk+fx, jre+fx, jdk+crac, jre+crac, jdk+jmods, jdk+jcef, jre+jcef, jdk+ft, or jre+ft. Support varies by distribution. jdk
architecture Package architecture. Canonical values are x86, x64, armv7, aarch64, ppc64le, ppc64, and s390x. Aliases ia32, amd64, arm, and arm64 are normalized. Runner architecture
jdk-file Local compressed JDK archive. Requires distribution: jdkfile.
check-latest Check remote metadata for the latest version satisfying the version spec before using the runner tool cache. false
force-download Always download Java and replace any matching version in the tool cache. false
set-default Add Java to PATH and set JAVA_HOME. When false, only version-specific JAVA_HOME_<major>_<arch> variables are set. true
problem-matcher Register Java compiler and uncaught exception problem matchers. true
verify-signature Verify downloaded Java package signatures when supported. Currently supported for temurin and microsoft. false
verify-signature-public-key ASCII-armored GPG public key to use for signature verification. Overrides the bundled key.
token Token for fetching GitHub.com-hosted version manifests, useful on GitHub Enterprise Server when unauthenticated requests are rate-limited. ${{ github.token }} on GitHub.com; empty string on GHES
cache Enable dependency caching for maven, gradle, or sbt.
cache-dependency-path Dependency file paths used for cache key hashing. Supports globs and multiline values. Auto-detected by package manager
cache-path Cache paths to use instead of the package manager's default dependency cache path. Supports multiline values and exclusions.
cache-read-only Restore caches without saving changes in the post step. false
server-id Maven repository ID used in generated settings.xml. github
server-username-env-var Environment variable name for Maven repository username. GITHUB_ACTOR
server-password-env-var Environment variable name for Maven repository password or token. GITHUB_TOKEN
settings-path Directory where settings.xml is written. ~/.m2
overwrite-settings Overwrite an existing settings.xml. true
gpg-private-key GPG private key to import.
gpg-passphrase-env-var Environment variable name for the GPG private key passphrase. GPG_PASSPHRASE when a key is set
mvn-toolchain-id Maven Toolchain ID. When multiple Java versions are installed, the number of IDs must match the number of versions. ${distribution}_${java-version}
mvn-toolchain-vendor Maven Toolchain vendor value. ${distribution}
show-download-progress Keep Maven artifact download and transfer progress in logs. When false, the action adds -ntp to MAVEN_ARGS. false

Deprecated aliases jdkFile, server-username, server-password, and gpg-passphrase remain accepted for compatibility, but should be replaced with the current input names.

Outputs

Output Description
distribution Distribution that was installed.
version Actual Java version that was installed.
path Installation path, also used for JAVA_HOME when set-default is enabled.
cache-hit Whether an exact dependency cache match was restored.
cache-primary-key Primary cache key computed for the selected package manager. Empty when caching is disabled or skipped.

Supported distributions

Keyword Distribution License
corretto Amazon Corretto License
dragonwell Alibaba Dragonwell JDK License
graalvm Oracle GraalVM License
graalvm-community GraalVM Community License
jetbrains JetBrains Runtime License
kona Tencent Kona JDK License
liberica Liberica JDK License
liberica-nik Liberica Native Image Kit License
microsoft Microsoft Build of OpenJDK License
oracle Oracle JDK License
oracle-openjdk Oracle OpenJDK License
sapmachine SAP SapMachine JDK/JRE License
semeru IBM Semeru Runtime Open Edition License
temurin Eclipse Temurin License
zulu Azul Zulu OpenJDK License
jdkfile Custom JDK archive

Note

Distribution availability, package variants, architectures, and version metadata differ by vendor. Check the vendor documentation when a specific version or platform matters.

Additional distribution notes:

  • Oracle OpenJDK builds are archived after a limited number of releases and no longer receive security updates. To continue receiving security patches, use Oracle JDK or another vendor.
  • Azul Zulu maps arm64 to aarch64 when querying the Azul Metadata API.
  • GraalVM Community is available as distribution: graalvm-community for stable JDK 17 and later releases.
  • On Ubuntu runners, commands executed with sudo do not inherit the JAVA_HOME and PATH set by setup-java and may fall back to the system-default JDK.

Supported version syntax

java-version accepts exact versions, version ranges, early-access versions, and latest.

Syntax Examples
Major version 8, 11, 17, 21, 25
Specific feature or patch version 11.0, 11.0.4, 17.0, 8.0.282+8
JEP 322 multi-field versions 11.0.9.1, 18.0.1.1
Early access 15-ea, 15.0.0-ea, 27-ea
Latest stable GA release latest

When check-latest is false, the action first tries the runner tool cache for the requested distribution, package type, architecture, and version range. It downloads Java only when no matching cached version is found. When check-latest is true, the action checks remote metadata first and downloads if the cached version is not current.

GitHub-hosted runners primarily pre-cache Eclipse Temurin JDKs. See the installed Java versions for Ubuntu, Windows, and macOS. On a fresh GitHub-hosted runner, requests for other distributions usually miss the tool cache and resolve from remote metadata. For broad version ranges such as a major version (21, 25), this often behaves similarly to check-latest: true because the action downloads the latest available release that satisfies the range.

Download integrity and signatures

setup-java automatically verifies downloaded archive checksums when a selected distribution publishes an authoritative checksum. Automatic checksum verification currently applies to temurin, semeru, corretto, dragonwell, kona, sapmachine, graalvm, graalvm-community, zulu, oracle, oracle-openjdk, microsoft, and jetbrains.

Distributions or individual releases without an authoritative checksum continue to install normally, with the omission reported in debug logs. Archives resolved directly from the runner tool cache are not downloaded again and are not reverified.

Use verify-signature: true to verify package signatures for distributions that support it. Currently supported distributions are temurin and microsoft; setting it for an unsupported distribution fails the workflow.

Caching dependencies

Set cache to maven, gradle, or sbt to cache dependencies with minimal configuration.

steps:
  - uses: actions/checkout@v7
  - uses: actions/setup-java@v6
    with:
      distribution: temurin
      java-version: '25'
      cache: maven
  - run: mvn verify

The primary dependency cache key is setup-java-<runner-os>-<node-arch>-<package-manager>-<file-hash>, where <node-arch> is the runner's Node.js process architecture. The primary cache stores dependency directories such as ~/.m2/repository, ~/.gradle/caches, or the sbt cache paths. Its file hash is based on these files by default:

Package manager Files used for the primary dependency-cache key
Gradle **/*.gradle*, **/gradle-wrapper.properties, buildSrc/**/Versions.kt, buildSrc/**/Dependencies.kt, gradle/*.versions.toml, **/versions.properties
Maven **/pom.xml, **/.mvn/wrapper/maven-wrapper.properties, **/.mvn/extensions.xml
sbt **/*.sbt, **/project/build.properties, **/project/**.scala, **/project/**.sbt

Use cache-dependency-path to override the files used for key hashing, especially in monorepos:

- uses: actions/setup-java@v6
  with:
    distribution: temurin
    java-version: '25'
    cache: gradle
    cache-dependency-path: |
      sub-project/*.gradle*
      sub-project/**/gradle-wrapper.properties

Use cache-path when the build tool stores dependencies outside the default location:

- uses: actions/setup-java@v6
  with:
    distribution: temurin
    java-version: '25'
    cache: maven
    cache-path: |
      /custom/maven/repository
      !/custom/maven/repository/**/*.lastUpdated
- run: mvn -Dmaven.repo.local=/custom/maven/repository verify

cache-path changes what is restored and saved, but not the cache key. Jobs that should share a cache key must use the same OS, architecture, package manager, dependency files, and cache paths.

Read-only caches

Set cache-read-only: true to restore dependency caches without saving changes in the post action. This is useful for pull requests, merge queues, short-lived branches, and matrix fan-out jobs that should only consume caches produced elsewhere.

- uses: actions/setup-java@v6
  with:
    distribution: temurin
    java-version: '25'
    cache: maven
    cache-read-only: ${{ github.ref != 'refs/heads/main' }}

For matrix fan-out, seed the cache once and make matrix jobs read-only consumers:

jobs:
  seed-cache:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7
      - uses: actions/setup-java@v6
        with:
          distribution: temurin
          java-version: '25'
          cache: maven
      - run: mvn dependency:go-offline dependency:resolve-plugins

  build:
    needs: seed-cache
    runs-on: ubuntu-latest
    strategy:
      matrix:
        goal: [test, verify, package]
    steps:
      - uses: actions/checkout@v7
      - uses: actions/setup-java@v6
        with:
          distribution: temurin
          java-version: '25'
          cache: maven
          cache-read-only: true
      - run: mvn ${{ matrix.goal }}

Wrapper caches

Maven and Gradle wrapper distributions are restored and saved as additional cache entries, separate from the primary dependency cache. These entries have their own keys in the form setup-java-<runner-os>-<node-arch>-<wrapper-cache-name>-<file-hash>.

Package manager Wrapper cache name Cached path Files used for wrapper-cache key
Maven maven-wrapper ~/.m2/wrapper/dists **/.mvn/wrapper/maven-wrapper.properties
Gradle gradle-wrapper ~/.gradle/wrapper **/gradle-wrapper.properties

These wrapper caches are independent from dependency caches, so they remain useful even when dependency files change frequently. The wrapper properties are also part of the Maven and Gradle primary dependency-cache key because wrapper changes can affect how dependencies are resolved, but the wrapper distribution files themselves are stored in the separate wrapper cache entries above.

For advanced Gradle caching features such as build output caching, configuration cache support, encrypted cache storage, cleanup, and fine-grained cache control, consider gradle/actions/setup-gradle.

Cache segment restore timeout

Cache downloads are split into segments. To reduce the chance of a stuck segment blocking a workflow, set SEGMENT_DOWNLOAD_TIMEOUT_MINS:

env:
  SEGMENT_DOWNLOAD_TIMEOUT_MINS: '5'
steps:
  - uses: actions/checkout@v7
  - uses: actions/setup-java@v6
    with:
      distribution: temurin
      java-version: '25'
      cache: gradle
  - run: ./gradlew build --no-daemon

Multiple JDKs and Maven toolchains

Install multiple Java versions by providing a multiline java-version value. All configured JDKs are installed. The last one added to PATH becomes the default.

steps:
  - uses: actions/setup-java@v6
    with:
      distribution: temurin
      java-version: |
        8
        11
        17
        21
        25

Other installed JDKs are available through version-specific variables such as JAVA_HOME_17_X64. To use a specific version later in the job, set JAVA_HOME and prepend its bin directory to PATH.

setup-java writes a Maven Toolchains declaration for each installed JDK. When multiple JDKs are installed, the declaration contains all of them. Customize the generated toolchain values with mvn-toolchain-id and mvn-toolchain-vendor.

Testing with a Java matrix

jobs:
  build:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        java: ['8', '11', '17', '21', '25']
    name: Java ${{ matrix.java }}
    steps:
      - uses: actions/checkout@v7
      - uses: actions/setup-java@v6
        with:
          distribution: temurin
          java-version: ${{ matrix.java }}
      - run: java --version
      - run: mvn verify

Publishing packages

setup-java generates Maven settings.xml and Maven Toolchains configuration. For Gradle publishing, it installs Java for the workflow; the Gradle build file remains responsible for reading credentials from environment variables.

Maven

steps:
  - uses: actions/checkout@v7
  - uses: actions/setup-java@v6
    with:
      distribution: temurin
      java-version: '25'
      server-id: github
      server-username-env-var: GITHUB_ACTOR
      server-password-env-var: GITHUB_TOKEN
  - run: mvn --batch-mode deploy
    env:
      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

GPG signing

steps:
  - uses: actions/checkout@v7
  - uses: actions/setup-java@v6
    with:
      distribution: temurin
      java-version: '25'
      gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }}
      gpg-passphrase-env-var: GPG_PASSPHRASE
  - run: mvn --batch-mode deploy
    env:
      GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}

Maven GPG signing requires maven-gpg-plugin 3.2.0 or newer because setup-java passes the passphrase through gpg.passphraseEnvName.

Recommended permissions

When using the setup-java action in your GitHub Actions workflow, it is recommended to set the following permissions to ensure proper functionality:

permissions:
  contents: read # access to check out code and install dependencies

Publishing workflows may require additional permissions depending on the target registry.

Advanced usage

See advanced usage for detailed examples:

License

The scripts and documentation in this project are released under the MIT License.

Contributions

Contributions are welcome. See our Contributor's Guide.

Code of Conduct

👋 Be nice. See our code of conduct

About

Set up your GitHub Actions workflow with a specific version of Java

Resources

Code of conduct

Security policy

Stars

Watchers

Forks

Releases

Packages

Used by

Contributors

Languages