Install the Java agent in an existing Gradle project with Docker

This example uses a sample Gradle project, which includes the Application Plugin and the Docker Plugin to build a Java web application. It also runs JUnit 5 integration tests that verify the web application's behavior. As part of the process, you will include Contrast in the Docker image used for testing so that Contrast Assess analyzes your code during integration testing. See an example of a Gradle project in our Github repo.

Note

Any part of the following procedures that refer to any form of packaging or distribution are meant for your organization's internal use. Do not distribute Contrast with your application or Docker container outside of your organization. See Contrast's Terms of Service agreement for more information.

To add the Contrast Java agent to an existing Gradle project with Docker:

  1. Use the agent keys to configure the agent's communication with Contrast. You'll need these keys:

  2. If you're using a Unix-like operating system, create a file for exporting the agent key values as Contrast environment variables.

  3. Open a command prompt and run the following command. Be sure to replace <contrast_url>, <your_api_key>, <agent_user_name> and <agent_user_service_key> with the Contrast URL, API key, username and service key values you obtained from the Contrast:

    $ tee -a ~/.contrastrc > /dev/null
    export CONTRAST__API__URL=<contrast_url>
    export CONTRAST__API__API_KEY=<your_api_key>
    export CONTRAST__API__USER_NAME=<agent_user_name>
    export CONTRAST__API__SERVICE_KEY=<agent_user_service_key>
  4. Press CTRL+D when you're finished typing all four lines of input to save the values to the $HOME/.contrastrc file.

  5. Run the .contrastrc script in the current shell to export the variables to your environment:

    $ . ~/.contrastrc

    Note

    If using Windows, refer to Microsoft's documentation to learn how to set environment variables.

    Tip

    You can configure the Contrast Java agent using a file, Java system properties or environment variables. Use environment variables for credentials and for connecting with Contrast. These values aren't likely to change across the projects in your local development environment. This method is also safer than putting your credentials directly in your build script.

    If you close the terminal where you ran the .contrastrc script, you'll have to re-run it when you open a new terminal. Add ~/.contrastrc to the script that initializes your interactive shell to make the configuration persist across terminal sessions. For example, if your shell program is Bash, you can do this by running echo ~/.contrastrc` | tee -a ~/.bashrc.

  6. Open a command prompt, and run the following command to clone Contrast's examples repository:

    $ git clone https://github.com/Contrast-Security-OSS/contrast-java-examples.git
  7. Enter the gradle-docker directory:

    $ cd contrast-java-examples/gradle-docker
  8. Run a test build to make sure everything is working:

    $ ./gradlew build
    
    BUILD SUCCESSFUL in 3s
    4 actionable tasks: 3 executed, 1 up-to-date

    Note

    On Windows, run gradlew.bat build instead.

  9. If this doesn't work, check to make sure you have Java 8 correctly installed:

    $ java -version
    java version "1.8.0_131"
    Java(TM) SE Runtime Environment (build 1.8.0_131-b11)
    Java HotSpot(TM) 64-Bit Server VM (build 25.131-b11, mixed mode)
  10. If you've made changes, run the build again. If it still doesn't work, open an issue that explains the problem.

  11. Add a dependency configuration and include a dependency on the Contrast Java agent:

    configurations {
        contrastAgent
    }
    def contrast_version = "3.6.3.8220"
    
    dependencies {
        // ... other dependencies omitted
        contrastAgent "com.contrastsecurity:contrast-agent:$<contrast_version>"
    }
  12. Add a task for copying the agent into a directory of the project:

    task("copyAgent", type: Copy) {
        from configurations.contrastAgent
        into "$<projectDir>/lib"
    }
    
    run.dependsOn copyAgent
    assemble.dependsOn copyAgent
  13. Add the -javaagent property to the JVM arguments passed to the application by modifying the application block of build.gradle:

    application {
      // ... rest of block omitted
      def agentBuildPath = "lib/contrast-agent-$<contrast_version>.jar"
      def agentProjectPath = Paths.get(getProjectDir().toURI()).resolve(agentBuildPath)
    
    
      applicationDefaultJvmArgs = [
              "-javaagent:$<agentProjectPath.toString()>"
      ]
    }
  14. Run the application:

    $ ./gradlew run

    Note

    On Windows, run gradlew.bat run instead.

  15. The application will now start up with Contrast. If you do any manual testing, any security related findings are reported to Contrast. You can press CTRL+C to stop the application.

  16. Configure the Distribution Plugin to include the Contrast agent JAR in the bundles created when you run gradle build. (The Distribution Plugin was included when you included the Application Plugin.)

    application {
    
      // ... rest of application config omitted
    
      distributions {
        main {
          contents {
            from("$<projectDir>/lib") {
                into "lib"
            }
          }
        }
      }
    }
  17. The -javaagent points to a JAR file in your project directory, not the JAR file in the application bundle. To point to the correct JAR file, configure the startScripts task to use the correct path in the bundle.

    application {
    
      // ... rest of application config omitted
    
      startScripts {
        doLast {
          def shFile = new File(getOutputDir(), project.name)
          shFile.text = shFile.text.replace(agentProjectPath.toString(), "\$APP_HOME/$<agentBuildPath>")
          def batFile = new File(getOutputDir(), "$<project.name>.bat")
          batFile.text = batFile.text.replace(agentProjectPath.toString(), "%APP_HOME%\\lib\\contrast-agent-$<contrast_version>.jar")
        }
      }
    }
    
  18. Pass the configuration variables into the container by adding the following commands to the createContainer task in build.gradle:

    task createContainer(type: DockerCreateContainer) {
        // ... rest of the config omitted
    
        envVars = [
            CONTRAST__API__URL: System.getenv("CONTRAST__API__URL"),
            CONTRAST__API__USER_NAME: System.getenv("CONTRAST__API__USER_NAME"),
            CONTRAST__API__SERVICE_KEY: System.getenv("CONTRAST__API__SERVICE_KEY"),
            CONTRAST__API__API_KEY: System.getenv("CONTRAST__API__API_KEY"),
            CONTRAST__APPLICATION__NAME: "${project.name}-how-to"
        ]
    }
  19. Run the build again:

    ./gradlew clean build

    Note

    On Windows, run gradlew.bat clean build instead.

    The Docker container now runs the application with Contrast enabled. When the integration test runs, it detects the vulnerable endpoint and reports it to Contrast. To see the vulnerability report, log in to the Contrast, navigate to the Vulnerabilities grid, and filter your view by the application name gradle-docker-how-to.

Tip

To integrate Contrast further with your Gradle build, check out the Contrast Gradle Plugin. You can configure its contrastVerify task to fail your Gradle build when Contrast detects vulnerabilities in your test run.