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 validationValidate Java e2eValidate 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@v5with:
distribution: temurinjava-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.
  • Caches downloaded JDK installations between jobs.
  • 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.
  • Added the oracle-openjdk distribution for OpenJDK builds from Oracle.
  • Added java-version: latest to resolve the newest stable GA release from the distribution's remote metadata.
  • JDK downloads now automatically verify authoritative checksums for supported distributions.
  • Added force-download: true to bypass the tool cache and perform a reproducible fresh install.
  • Dependency caching now supports custom paths with cache-path and restore-only operation with cache-read-only: true.
  • Downloaded JDKs are now cached automatically when cache is set; use cache-jdk to enable or disable it independently.
  • Set problem-matcher: false to disable Java compiler and uncaught-exception annotations.
  • GraalVM distributions now set GRAALVM_HOME in addition to JAVA_HOME.
  • Invalid boolean values, unsupported distribution/package/platform combinations, and mismatched Maven toolchain ID counts now fail with targeted errors.
  • 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

  • Upgraded the action runtime from Node 20 to Node 24. Self-hosted runners must use version v2.327.1 or later. See the runner release notes.
  • Added support for GraalVM Community and Tencent Kona.
  • Expanded java-version-file support with .sdkmanrc files and automatic distribution detection from SDKMAN and asdf vendor identifiers.
  • Added optional package-signature verification for Eclipse Temurin and Microsoft Build of OpenJDK downloads.
  • Added set-default: false for installing a JDK without changing JAVA_HOME or PATH.
  • Improved dependency caching with separate Maven and Gradle wrapper caches, Maven extension-aware cache keys, and the cache-primary-key output.
  • Improved Maven and Java build behavior by preserving toolchain entries across repeated action invocations, suppressing transfer progress by default, generating non-interactive Maven settings, and matching javac compiler errors.
  • Renamed the jdkFile input to jdk-file; the old name remains available as a deprecated alias.
  • See the complete V5 release history for enhancements and fixes across all V5 releases.

Older versions

Warning

actions/setup-java versions v1 through v4 are deprecated. Upgrade workflows to actions/setup-java@v5, the latest stable release.

Usage

Install Eclipse Temurin

steps:
- uses: actions/checkout@v7
- uses: actions/setup-java@v5with:
distribution: temurinjava-version: '25'
- run: java --version

Install Microsoft Build of OpenJDK

steps:
- uses: actions/checkout@v7
- uses: actions/setup-java@v5with:
distribution: microsoftjava-version: '25'
- run: java --version

Read the version from a file

steps:
- uses: actions/checkout@v7
- uses: actions/setup-java@v5with:
distribution: temurinjava-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@v5with:
distribution: temurinjava-version: latest
- run: java --version

latest resolves the newest stable GA release from remote metadata rather than from the runner tool cache. Distributions that do not publish a release listing (such as oracle and graalvm) resolve the newest GA feature version from the Adoptium available-releases API and then request that version from their own catalog. latest is not supported with java-version-file, early-access versions, or distribution: jdkfile.

Inputs

InputDescriptionDefault
java-versionJava version to install. Supports whole versions, semver ranges, early-access versions, and latest. Required unless java-version-file is set.
java-version-filePath to .java-version, .tool-versions, or .sdkmanrc. Used when java-version is not set.
distributionJava 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-packagePackage 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
architecturePackage architecture. Canonical values are x86, x64, armv7, aarch64, ppc64le, ppc64, and s390x. Aliases ia32, amd64, arm, and arm64 are normalized.Runner architecture
jdk-fileLocal compressed JDK archive. Requires distribution: jdkfile.
check-latestCheck remote metadata for the latest version satisfying the version spec before using the runner tool cache.false
force-downloadAlways download Java and replace any matching version in the tool cache.false
set-defaultAdd Java to PATH and set JAVA_HOME. When false, only version-specific JAVA_HOME_<major>_<arch> variables are set.true
problem-matcherRegister Java compiler and uncaught exception problem matchers.true
verify-signatureVerify downloaded Java package signatures when supported. Currently supported for temurin and microsoft.false
verify-signature-public-keyASCII-armored GPG public key to use for signature verification. Overrides the bundled key.
tokenToken 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
cacheEnable dependency caching for maven, gradle, or sbt.
cache-jdkCache downloaded JDK installations between jobs. When omitted, JDK caching is enabled only if cache is set. Set explicitly to true or false to override.Enabled when cache is set
cache-dependency-pathDependency file paths used for cache key hashing. Supports globs and multiline values.Auto-detected by package manager
cache-pathCache paths to use instead of the package manager's default dependency cache path. Supports multiline values and exclusions.
cache-read-onlyRestore dependency, wrapper, and JDK caches without saving changes in the post step.false
server-idMaven repository ID used in generated settings.xml.github
server-username-env-varEnvironment variable name for Maven repository username.GITHUB_ACTOR
server-password-env-varEnvironment variable name for Maven repository password or token.GITHUB_TOKEN
settings-pathDirectory where settings.xml is written.~/.m2
overwrite-settingsOverwrite an existing settings.xml.true
gpg-private-keyGPG private key to import.
gpg-passphrase-env-varEnvironment variable name for the GPG private key passphrase.GPG_PASSPHRASE when a key is set
mvn-toolchain-idMaven Toolchain ID. When multiple Java versions are installed, the number of IDs must match the number of versions.${mvn-toolchain-vendor}_${java-version}
mvn-toolchain-vendorMaven Toolchain vendor value.${distribution}
show-download-progressKeep Maven artifact download and transfer progress in logs. When false, the action adds -ntp to MAVEN_ARGS.false
  • java-package: Supported package types are jdk, jre, jdk+fx, jre+fx, jdk+crac, jre+crac, jdk+jmods, jdk+jcef, jre+jcef, jdk+ft, and jre+ft. Availability varies by distribution.

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

Outputs

OutputDescription
distributionDistribution that was installed.
versionActual Java version that was installed.
pathInstallation path, also used for JAVA_HOME when set-default is enabled.
cache-hitWhether an exact dependency cache match was restored.
cache-primary-keyPrimary cache key computed for the selected package manager. Empty when caching is disabled or skipped.

Supported distributions

KeywordDistributionLicense
correttoAmazon CorrettoLicense
dragonwellAlibaba Dragonwell JDKLicense
graalvmOracle GraalVMLicense
graalvm-communityGraalVM CommunityLicense
jetbrainsJetBrains RuntimeLicense
konaTencent Kona JDKLicense
libericaLiberica JDKLicense
liberica-nikLiberica Native Image KitLicense
microsoftMicrosoft Build of OpenJDKLicense
oracleOracle JDKLicense
oracle-openjdkOracle OpenJDKLicense
sapmachineSAP SapMachine JDK/JRELicense
semeruIBM Semeru Runtime Open EditionLicense
temurinEclipse TemurinLicense
zuluAzul Zulu OpenJDKLicense
jdkfileCustom 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.

SyntaxExamples
Major version8, 11, 17, 21, 25
Specific feature or patch version11.0, 11.0.4, 17.0, 8.0.282+8
JEP 322 multi-field versions11.0.9.1, 18.0.1.1
Early access15-ea, 15.0.0-ea, 27-ea
Latest stable GA releaselatest

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. Installations resolved directly from the runner tool cache — including JDKs preinstalled on the runner image and JDKs installed by an earlier step of the same job — are not downloaded again and are not reverified, even when verify-signature: true is set. Use force-download: true to always download and verify the archive.

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

setup-java manages three kinds of caches. Each one is restored and saved as a separate cache entry.

CacheWhat it storesKey based onHow it is enabled
Dependency cacheDownloaded dependencies, such as ~/.m2/repository, ~/.gradle/caches, or the sbt cache pathsRunner OS, architecture, package manager, and a hash of the dependency filesSet cache to maven, gradle, or sbt
Wrapper cachesMaven and Gradle wrapper distributions (~/.m2/wrapper/dists, ~/.gradle/wrapper)Runner OS, architecture, wrapper cache name, and a hash of the wrapper propertiesSet cache to maven or gradle
JDK cacheThe downloaded JDK installationRunner OS, architecture, distribution, package type, resolved version, release identity, and signature-verification identityEnabled implicitly whenever cache is set, or explicitly with cache-jdk: true. Opt out with cache-jdk: false

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

steps:
- uses: actions/checkout@v7
- uses: actions/setup-java@v5with:
distribution: temurinjava-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 managerFiles 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@v5with:
distribution: temurinjava-version: '25'cache: gradlecache-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@v5with:
distribution: temurinjava-version: '25'cache: mavencache-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.

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 managerWrapper cache nameCached pathFiles used for wrapper-cache key
Mavenmaven-wrapper~/.m2/wrapper/dists**/.mvn/wrapper/maven-wrapper.properties
Gradlegradle-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.

Caching JDK installations

The JDK cache stores the downloaded JDK installation so later runs skip the download. It is enabled implicitly whenever dependency cache is set, so most workflows that cache dependencies are already caching the JDK. Set cache-jdk: true to enable it without dependency caching, or cache-jdk: false to opt out while keeping dependency caching. With neither cache nor cache-jdk set, nothing is cached.

Important

Because JDK caching is on by default whenever cache is set, review Caching JDK installations for the full cache/cache-jdk matrix, cache identity and storage impact.

Read-only caches

Set cache-read-only: true to restore dependency, wrapper, and JDK 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@v5with:
distribution: temurinjava-version: '25'cache: mavencache-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-lateststeps:
- uses: actions/checkout@v7
- uses: actions/setup-java@v5with:
distribution: temurinjava-version: '25'cache: maven
- run: mvn dependency:go-offline dependency:resolve-pluginsbuild:
needs: seed-cacheruns-on: ubuntu-lateststrategy:
matrix:
goal: [test, verify, package]steps:
- uses: actions/checkout@v7
- uses: actions/setup-java@v5with:
distribution: temurinjava-version: '25'cache: mavencache-read-only: true
- run: mvn ${{ matrix.goal }}

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@v5with:
distribution: temurinjava-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@v5with:
distribution: temurinjava-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-lateststrategy:
matrix:
java: ['8', '11', '17', '21', '25']name: Java ${{ matrix.java }}steps:
- uses: actions/checkout@v7
- uses: actions/setup-java@v5with:
distribution: temurinjava-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@v5with:
distribution: temurinjava-version: '25'server-id: githubserver-username-env-var: GITHUB_ACTORserver-password-env-var: GITHUB_TOKEN
- run: mvn --batch-mode deployenv:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

GPG signing

steps:
- uses: actions/checkout@v7
- uses: actions/setup-java@v5with:
distribution: temurinjava-version: '25'gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }}gpg-passphrase-env-var: GPG_PASSPHRASE
- run: mvn --batch-mode deployenv:
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

2.0k stars

Watchers

89 watching

Forks

Releases

Packages

Used by

Contributors

Languages