Giter Club home page Giter Club logo

gradle-jdks's Introduction

Autorelease

gradle-jdks

Automatically provision specific versions of JDKs for Gradle tasks that require JDKs (JavaCompile, Test, JavaExec etc) . Choose from a variety of different JDK vendors which can be automatically installed on multiple OSs.

Motivation

Gradle has a built-in concept of auto-provisioning Java Toolchains, which will automatically install JDKs if they do not exist on system running Gradle, however it's lacking in some aspects:

  1. Gradle always uses AdoptOpenJDK/Adoptium.
    1. You may prefer a different JDK vendor. We use Azul Zulu for their MTS support. It is important to us to develop and test with the same JDK we use in prod.
    2. Adoptium does not provide macos aarch64 for Java 11, which we need for Apple Silicon Macbooks.
  2. Once Gradle finds an appropriate JDK on disk for that Java language version, it is always used and never updated.
    1. As a company with tens of millions of lines of Java, we often bump into JVM bugs. It's highly desirable we test and deploy using the exact same version of JDKs.
    2. Similarly, it's important to us that the exact same JDK versions are used on local machines as well as CI.
  3. Gradle does not handle JDK CA certificates.
    1. Many companies use TLS interception when network calls are made outside their corporate network. Gradle provides no way to install the relevant CA certificates into auto-provisioned JDKs. This means they cannot be used in such an environment, or require manual patching.
  4. You cannot easily set up a mirror for auto-provisioned JDK downloads.
    1. There's a Gradle property you can set to change to server base uri, but this still leaves you writing and maintaining a service that replicates the adoptium api.
    2. An internal corporate mirror can be 100x faster than a public one, especially for CI builds.

gradle-jdks solves all of these problems:

  1. You can choose your favoured JDK vendor.
  2. Use the same JDK version for representative, reproducible builds on dev machines and in CI.
  3. Automatically add JDK CA certificates.
  4. Point to an internal mirror for JDKs.

Usage

Palantirians: you probably shouldn't use this plugin directly - either use gradle-jdks-latest for OSS or gradle-jdks-internal for internal projects which will set everything up for you.

First, you must apply the plugin. In the root project, Either use the new plugin syntax:

plugins {
   id 'com.palantir.jdks' version '<latest version>'
}

or the old buildscript method:

buildscript {
   repositories {
      mavenCentral()
   }
   
   dependencies {
      classpath 'com.palantir.gradle.jdks:gradle-jdks:<latest-version>'
   }
}

apply plugin: 'com.palantir.jdks'

Next up comes configuring the JDKs plugin:

jdks {
   // Required: For each Java major version you use, you need to specify
   //           a distribution and version.
   jdk(11) {
      distribution = 'azul-zulu'
      jdkVersion = '11.54.25-11.0.14.1'
   }
   
   jdk(17) {
      distribution = 'amazon-corretto'
      jdkVersion = '17.0.3.6.1'
   }
   
   // Optional: For each distribution, you can set a base url for a
   //           mirror to use instead of the default public mirror.
   // Default:  Whatever mirror is publicly provided by the vendor
   jdkDistribution('azul-zulu') {
      baseUrl = 'https://internal-corporate-mirror/azul-zulu-cdn-mirror'
   }
   
   // Optional: You can specify CA certs which will be installed into
   //           the extracted JDK to work with TLS interception.
   // Default:  No CA certs are added.
   caCerts.put 'corporate-tls-cert', '''
      -----BEGIN CERTIFICATE-----
      // snip
      -----END CERTIFICATE-----
   '''.stripIndent(true)
   
   // Optional: Where to store the JDKs on disk. You almost certainly
   //           do not need to change this. 
   // Default:  $HOME/.gradle/gradle-jdks
   jdkStorageLocation = System.getProperty("user.home") + '/custom/location'
}

Behind the scenes, gradle-jdks applies com.palantir.baseline-java-versions (another gradle plugin - more docs in link) to handle configuring the Java language versions. You will need to configure this plugin as well to tell it what Java language versions:

// Read the docs at https://github.com/palantir/gradle-baseline#compalantirbaseline-java-versions
javaVersions {
   libraryTarget = 11
   distributionTarget = 17
}

What JDK distributions are supported?

Supported JDK distribution can be found here.

New JDK distributions are easily added - you just need to:

  1. Add an entry to JdkDistributionName
  2. Add a JdkDistribution - Azul Zulu example.
  3. Add the JDK distribution here.
  4. Write some tests to check the path is being built correctly - Azul Zulu example.
  5. Make a PR.

What does this not do?

  1. Run the Gradle wrapper/daemon with a certain JDK
    • This plugin will only run common tasks that require JDKs, like JavaCompile, Test, JavaExec, GroovyCompile etc (the aforementioned com.palantir.baseline-java-versions does this).
    • The daemon itself still requires a preinstalled JDK.
    • In future, we hope to implement this feature, although it is not currently scheduled to be worked on.

How can I see what JDK tasks are running with?

If you run you gradle invocation with --info --rerun-tasks, the JDK will be visible in the output:

$ ./gradlew compileJava --info --rerun-tasks
> Task :my-project:compileJava
Compiling with toolchain '/Users/username/.gradle/gradle-jdks/azul-zulu-17.34.19-17.0.3-a3ceab47882436a6'.

Related projects

  • gradle-jdks-latest applies this plugin and configures the latest JDK releases - primarily exists for Palantir use, enforcing consistency across our open-source projects.

gradle-jdks's People

Contributors

crogers avatar svc-excavator-bot avatar svc-autorelease avatar svc-changelog avatar carterkozak avatar j-baker avatar mglazer avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.