Java
You can build and test a Java application using a Linux platform on Harness Cloud or a self-managed Kubernetes cluster build infrastructure.
This guide assumes you've created a Harness CI pipeline.
Install dependencies
Use Run steps to install dependencies in the build environment.
              - step:
                   type: Run
                   name: build
                   identifier: build
                   spec:
                     connectorRef: YOUR_IMAGE_REGISTRY_CONNECTOR
                     image: maven:3.8-jdk-11
                     shell: Sh
                     command: |-
                       mvn clean package dependency:copy-dependencies
                   - step:
                       type: Run
                       name: check dependencies
                       identifier: check_dependencies
                       spec:
                         connectorRef: YOUR_IMAGE_REGISTRY_CONNECTOR
                         image: maven:3.8-jdk-11
                         shell: Sh
                         command: |-
                           mvn dependency-check:check -U -DskipTests
                         reports:
                           type: JUnit
                           spec:
                             paths:
                               - /harness/target/*.xml
In addition to Run steps, Plugin steps are also useful for installing dependencies.
You can use Background steps to run dependent services that are needed by multiple steps in the same stage.
Cache dependencies
- Cache Intelligence
- Save and Restore Cache steps
Cache your Java dependencies with Cache Intelligence.
Add caching.enabled.true to your stage.spec:
- stage:
    spec:
      caching:
        enabled: true
You can use built-in steps to:
If you're using Maven, you must reference pom.xml in the key value for your Save Cache and Restore Cache steps, for example:
spec:
  key: cache-{{ checksum "pom.xml" }}
Additionally, you must include /root/.m2 in the sourcePaths for your Save Cache step, for example:
spec:
  sourcePaths:
    - /root/.m2
Here's an example of a pipeline with Save Cache to S3 and Restore Cache from S3 steps.
            steps:
              - step:
                  type: RestoreCacheS3
                  name: Restore Cache From S3
                  identifier: Restore_Cache_From_S3
                  spec:
                    connectorRef: AWS_Connector
                    region: us-east-1
                    bucket: your-s3-bucket
                    key: cache-{{ checksum "pom.xml" }}
                    archiveFormat: Tar
              - step:
                  type: Run
                  ...
              - step:
                  type: BuildAndPushDockerRegistry
                  ...
              - step:
                  type: SaveCacheS3
                  name: Save Cache to S3
                  identifier: Save_Cache_to_S3
                  spec:
                    connectorRef: AWS_Connector
                    region: us-east-1
                    bucket: your-s3-bucket
                    key: cache-{{ checksum "pom.xml" }}
                    sourcePaths:
                      - /root/.m2
                    archiveFormat: Tar
Build and run tests
You can use Run or Test steps to run tests in CI pipelines.
- Run step
- Test step (Test Intelligence)
This example uses two Run steps to build and test with Maven.
- step:
    type: Run
    name: build
    identifier: build
    spec:
      connectorRef: YOUR_IMAGE_REGISTRY_CONNECTOR
      image: maven:3.8-jdk-11
      shell: Sh
      command: |
        mvn clean package dependency:copy-dependencies
- step:
    type: Run
    name: run test
    identifier: run_test
    spec:
      shell: Sh
      command: |-
        mvn test
      reports:
        type: JUnit
        spec:
          paths:
            - target/surefire-reports/*.xml
You must use the Test step for your unit tests if you want to leverage Harness' Test Intelligence feature.
              - step:
                  type: Test
                  name: RunTestsWithIntelligence
                  identifier: RunTestsWithIntelligence
                  spec:
                    command: |-
                      mvn test
                      mvn package -DskipTests
                    shell: Sh
                    connectorRef: YOUR_IMAGE_REGISTRY_CONNECTOR
                    image: maven:3.8-jdk-11
                    intelligenceMode: true
                    reports:
                      - "target/surefire-reports/*.xml"
Visualize test results
If you want to view test results in Harness, make sure your test commands produce reports in JUnit XML format and that your steps include the reports specification.
reports:
  type: JUnit
  spec:
    paths:
      - target/surefire-reports/*.xml
Test splitting
Harness CI supports test splitting (parallelism) for both Run and Test steps.
Specify version
- Harness Cloud
- Self-managed
Java is pre-installed on Hosted Cloud runners. For details about all available tools and versions, go to Platforms and image specifications.
If your application requires a specific version of Java, you can use a Run, GitHub Action, or Plugin step to install it.
This example uses the GitHub Action step to run the setup-java action.
- step:
    type: Action
    name: setup java
    identifier: setup_java
    spec:
      uses: actions/setup-java@v3
      with:
        distribution: "temurin"
        java-version: "16"
You can use a Run or Plugin step to install Java versions that are not already installed on your host machine.
This example uses the Plugin step to run the GitHub Actions Drone plugin and run the setup-java action.
- step:
    identifier: setup_java
    name: setup java
    type: Plugin
    spec:
      connectorRef: YOUR_IMAGE_REGISTRY_CONNECTOR
      image: plugins/github-actions
      privileged: true
      settings:
        uses: actions/setup-java@v3
        with:
          distribution: "temurin"
          java-version: "17"
Full pipeline examples
Here's a YAML example of a pipeline that:
- Tests a Java code repo.
- Builds and pushes an image to Docker Hub.
This pipeline uses Harness Cloud build infrastructure, Cache Intelligence, and Test Intelligence.
If you copy this example, replace the placeholder values with appropriate values for your Harness project, connector IDs, account/user names, and repo names.
Pipeline YAML
pipeline:
  name: Build java
  identifier: Build_java
  projectIdentifier: default
  orgIdentifier: default
  properties:
    ci:
      codebase:
        connectorRef: YOUR_CODE_REPO_CONNECTOR_ID
        repoName: YOUR_REPO_NAME
        build: <+input>
  stages:
    - stage:
        name: Build
        identifier: Build
        description: ""
        type: CI
        spec:
          caching:
            enabled: true
          cloneCodebase: true
          platform:
            os: Linux
            arch: Amd64
          runtime:
            type: Cloud
            spec: {}
          execution:
            steps:
              - step:
                  type: Test
                  name: RunTestsWithIntelligence
                  identifier: RunTestsWithIntelligence
                  spec:
                    command: |-
                      mvn test
                      mvn package -DskipTests
                    shell: Sh
                    connectorRef: YOUR_IMAGE_REGISTRY_CONNECTOR
                    image: maven:3.8-jdk-11
                    intelligenceMode: true
                    reports:
                      - "target/surefire-reports/*.xml"
              - step:
                  type: BuildAndPushDockerRegistry
                  name: BuildAndPushDockerRegistry_1
                  identifier: BuildAndPushDockerRegistry_1
                  spec:
                    connectorRef: YOUR_DOCKER_CONNECTOR_ID
                    repo: YOUR_DOCKER_HUB_USERNAME/DOCKER_REPO_NAME
                    tags:
                      - <+pipeline.sequenceId>
Next steps
Now that you have created a pipeline that builds and tests a Java app, you could:
- Create triggers to automatically run your pipeline.
- Add steps to build and upload artifacts.
- Add a step to build and push an image to a Docker registry.