setup-java

repository·main·Indexed 24 days ago

https://github.com/actions/setup-java

GitHub Action for automating the installation and configuration of Java environments on runners. It supports various distributions (such as Temurin, Zulu, and Microsoft), build tools (Apache Maven, Gradle, sbt), and dependency caching. Version 6.0.0 introduces renamed environment variable inputs for security and removes legacy AdoptOpenJDK distributions.

Tokens
16.7K
Snippets
41
Records
67
Agent score
83%

What's inside setup-java

  1. Overview of setup-java functionality

    main

    The setup-java action is designed for GitHub Actions runners to manage Java and Scala environments. It provides the following capabilities:

    • Java Setup: Downloading and setting up requested Java versions and distributions.
    • Custom Java Extraction: Extracting and caching custom Java versions from local files.
    • Build Tool Configuration: Configuring runners for publishing using Apache Maven or Gradle.
    • Security: Configuring runners to use a GPG private key.
    • Dependency Caching: Caching dependencies for Apache Maven, Gradle, and sbt.
    • Error Handling: Registering problem matchers for error output.
    • Maven Toolchains: Supporting Maven Toolchains declaration for specified JDK versions.
  2. Install multiple JDKs with Maven Toolchains

    main

    The setup-java action automatically generates or extends a Maven Toolchains declaration (toolchains.xml).

    When you call setup-java multiple times in a single job with different distribution or java-version parameters, the toolchain entries are merged non-destructively. This allows you to accumulate multiple JDKs in your toolchain for a single build process. You can also use the jdkfile distribution to install custom JDKs from a downloaded archive.

    steps:
      - uses: actions/setup-java@v6
        with:
          distribution: '<distribution>'
          java-version: |
            8
            11
    
      - uses: actions/setup-java@v6
        with:
          distribution: '<distribution>'
          java-version: '15'
  3. How the Hosted Tool Cache works

    main

    GitHub Hosted Runners include a tool cache (located at the path specified by the RUNNER_TOOL_CACHE environment variable) containing pre-installed Java versions.

    setup-java optimizes runs by checking this cache first. If the requested distribution, version, and architecture match a version in the cache, the action adds that version to the PATH instead of downloading a new JDK. Currently, LTS versions of Eclipse Temurin (temurin) are commonly cached on GitHub-hosted runners.

  4. Install multiple JDKs in a single workflow

    main

    You can install multiple Java versions by providing a list to java-version. All versions are added to the PATH. The last version added becomes the default. Other versions remain discoverable via environment variables like JAVA_HOME_<major>_<arch>.

    Example:

       steps:
          - uses: actions/setup-java@v6
            with:
              distribution: '<distribution>'
              java-version: |
                8
                11
                15

    When multiple JDKs are installed, the action also generates a Maven Toolchains declaration referencing all installed versions.

  5. Migrate to V2 by specifying the mandatory distribution input

    main

    In V2, the distribution input is mandatory. You must specify one of the supported distributions. If you want to maintain the same behavior as V1, use the zulu keyword.

    General recommendation: Configure your CI with the same distribution used on your local development machine to ensure consistency.

    steps:
      - uses: actions/checkout@v2
      - uses: actions/setup-java@v2
        with:
          distribution: 'zulu'
          java-version: '11'
          java-package: jdk # optional (jdk or jre) - defaults to jdk
      - run: java -cp java HelloWorldApp
  6. Install a custom Java distribution from a local file in V2

    main

    To install Java from a local file on the runner in V2, set the distribution input to jdkfile and provide the path to the archive using the jdkFile input. You should also specify the architecture (e.g., x64).

    steps:
      - run: |
          download_url="https://github.com/AdoptOpenJDK/openjdk11-binaries/releases/download/jdk-11.0.10%2B9/OpenJDK11U-jdk_x64_linux_hotspot_11.0.10_9.tar.gz"
          wget -O $RUNNER_TEMP/java_package.tar.gz $download_url
      - uses: actions/setup-java@v2
        with:
          distribution: 'jdkfile'
          jdkFile: ${{ runner.temp }}/java_package.tar.gz
          java-version: '11.0.0'
          architecture: x64
  7. Select a Java distribution

    main

    To use actions/setup-java, you must provide both java-version and distribution inputs. The distribution value determines which vendor's build is installed (e.g., temurin, zulu, microsoft).

    steps:
      - uses: actions/checkout@v7
      - uses: actions/setup-java@v6
        with:
          distribution: 'temurin'
          java-version: '25'
  8. Contribute code to setup-java

    main

    To contribute code, you must submit a pull request from a feature branch. Code changes are located in the src folder as .ts files.

    Requirements:

    • All code contributions must include relevant tests. Unit tests are located in __tests__ and end-to-end tests are in workflows/ (look for files with the e2e prefix).
    • Tests should cover successful execution, edge cases, and potential errors.
    • You must ensure code is formatted and linted correctly using the provided scripts.
    • You must run the build script after making changes to transpile source code to javascript via NCC, otherwise changes will not be included in the final build.
  9. Publish Apache Maven packages to GitHub Packages or Maven Central

    main

    To publish Maven artifacts, use setup-java to automatically generate a settings.xml file containing the necessary server credentials.

    1. For GitHub Packages: Provide the server-id (matching the id in your pom.xml's distributionManagement) and use GITHUB_TOKEN as the password.
    2. For Maven Central: Provide the server-id, server-username-env-var, and server-password-env-var. These inputs define which environment variables Maven will use to read the username and password during mvn deploy.

    Important Notes:

    • The generated settings.xml is placed in $HOME/.m2 and will overwrite any existing file unless you set overwrite-settings: false.
    • The generated file automatically sets <interactiveMode>false</mode> to prevent CI hangs.
    • If using a shared self-hosted runner where $HOME might be shared, use settings-path to specify a unique location (e.g., ${{ github.workspace }}) and pass that path to Maven using mvn deploy -s <path>/settings.xml.
          - name: Set up Apache Maven Central
            uses: actions/setup-java@v6
            with:
              distribution: 'temurin'
              java-version: '11'
              server-id: maven # Value of the distributionManagement/repository/id field of the pom.xml
              server-username-env-var: MAVEN_USERNAME # env variable for username in deploy
              server-password-env-var: MAVEN_CENTRAL_TOKEN # env variable for token in deploy
    
          - name: Publish to Apache Maven Central
            run: mvn deploy -Dgpg.signer=bc
            env:
              MAVEN_USERNAME: maven_username123
              MAVEN_CENTRAL_TOKEN: ${{ secrets.MAVEN_CENTRAL_TOKEN }}
              MAVEN_GPG_KEY: ${{ secrets.MAVEN_GPG_PRIVATE_KEY }}
              MAVEN_GPG_PASSPHRASE: ${{ secrets.MAVEN_GPG_PASSPHRASE }}
  10. Install multiple JDKs without overriding the default

    main

    By default, the last JDK installed in a workflow becomes the default for JAVA_HOME and the PATH. To install additional JDKs that are discoverable but do not become the system default, use set-default: false.

    When set-default: false is used, the installed JDK is still accessible via:

    1. The environment variable JAVA_HOME_<major>_<arch> (e.g., JAVA_HOME_21_X64).
    2. The step output path.
    3. The Maven toolchains file.

    Note: If a single step installs multiple JDKs using a multiline java-version string, the set-default value applies to all of them.

    steps:
      - uses: actions/checkout@v7
      - uses: actions/setup-java@v6
        with:
          distribution: 'temurin'
          java-version: '17'
      - uses: actions/setup-java@v6
        id: setup-java-21
        with:
          distribution: 'temurin'
          java-version: '21'
          set-default: false
      - run: |
          echo "Default java:"
          java -version
          echo "Java 21 home: $JAVA_HOME_21_X64"
          echo "Java 21 path from output: ${{ steps.setup-java-21.outputs.path }}"
  11. Seed the Maven cache to ensure complete plugin dependencies

    main

    When using cache: maven, the action caches ~/.m2/repository. Because Maven resolves plugins lazily, a standard mvn compile might not download all necessary plugin dependencies. If these are missing, subsequent jobs (like test or package) will re-download them every time because the action does not re-save the cache on a hit.

    To fix this, run a "seed" command to resolve all dependencies and plugins before your main build.

    CommandResolves plugin dependencies?Notes
    mvn dependency:resolveNoProject dependencies only.
    mvn dependency:resolve-pluginsYesPlugins and their dependencies.
    mvn dependency:go-offlineYesProject and plugin dependencies (superset).
    mvn dependency:go-offline dependency:resolve-pluginsYesRecommended default for thoroughness.

    Implementation Patterns

    Pattern 1: Single job (Seed then Build)

    Use this if you want the seed and build to happen in one job. The cache is saved at the end of this run.

    steps:
      - uses: actions/checkout@v7
      - uses: actions/setup-java@v6
        with:
          distribution: 'temurin'
          java-version: '25'
          cache: 'maven'
      - name: Seed the Maven cache
        run: mvn dependency:go-offline dependency:resolve-plugins
      - name: Build with Maven
        run: mvn verify --file pom.xml

    Pattern 2: Separate seed job (Matrix friendly)

    Use this for matrix builds where multiple jobs share the same cache. The seed-cache job creates a comprehensive cache that all subsequent jobs reuse.

    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'
          - name: Seed the Maven cache
            run: mvn dependency:go-offline dependency:resolve-plugins
    
      build:
        needs: seed-cache
        runs-on: ubuntu-latest
        strategy:
          matrix:
            goal: ['test', 'verify', 'test -Pprofile1']
        steps:
          - uses: actions/checkout@v7
          - uses: actions/setup-java@v6
            with:
              distribution: 'temurin'
              java-version: '25'
              cache: 'maven'
          - name: Build
            run: mvn ${{ matrix.goal }} --file pom.xml
  12. Migrating to V6: Renamed environment variable inputs

    main

    In V6, inputs that accept the names of environment variables (rather than the credentials themselves) have been renamed to prevent confusion. While the old names exist as deprecated aliases that emit warnings, you should update your workflows to use the new names:

    | Old Input Name | New Input Name | | :--- | : | | server-username | server-username-env-var | | server-password | server-password-env-var | | gpg-passphrase | gpg-passphrase-env-var |