- Introducing Java toolchains
- Introducing Java toolchains support
- Project wide configuration
- Task level configuration
- Further benefits of toolchain usage
- Relaxing Java version constraints on Gradle
- What’s next for toolchains?
- Related Posts
- Different ways to configure java or JDK version in Gradle project
- How to configure source and target JDK version in gradle build
- How to install and configure the java version with gradle build?
- Conclusion
- How To Use Specific JDK Version For Gradle Build
- Problem Scenario
- Solution
Introducing Java toolchains
Building a Java project and running Gradle both require the installation of a JDK. Most Gradle users conveniently use the Java installation that is running Gradle to build and test their application.
While this is acceptable in simple cases, there are a number of issues with this approach. For example, if a build requires the same Java version to be used on all machines, each developer needs to know about that requirement and install that version manually.
It has been possible to configure Gradle to build a project with a different Java version than the one used to run Gradle. However, it has required configuring each task like compilation, test, and javadoc separately.
Gradle 6.7 introduces “Java toolchain support”. In a nutshell, it allows you to run Gradle with whatever version of Java you have installed, while Gradle builds the project with the version of Java declared in a single place. Gradle will automatically configure the build, detect already installed JDKs and download the required JDK if it is not already installed.
No more release or sourceCompatibility tweaks, no more wiki pages describing which JDK you should install for the build to work. The advantages are tremendous, let’s see how to use this!
Introducing Java toolchains support
Java toolchains support enables build authors to declare which Java version their project requires for compiling, testing and running their code.
Project wide configuration
Let’s start with what you, as a build author, need to do, at the minimum:
What do you get with the above in Gradle 6.7?
- All Java compilation tasks will use Java 11 to build. That means code in the main and test source sets, but also Java code in any custom source set you add, will be built with the configured Java version.
- All tests tasks, including the default test task and any additional custom Test task, will use Java 11 to run the tests.
- The javadoc task will use Java 11 to build the documentation.
In addition, with the application plugin, the run task will use Java 11 to start your application.
Behind the scenes, Gradle will have:
- Located a Java 11 installation, from a list of known locations such as asdf, jabba, SDKMAN! or standard locations per operating system
- Validated the installation and its version
- If no Java 11 installation was found, Gradle will attempt to download one from AdoptOpenJDK
If Gradle cannot find the requested Java version, you can tell it where to look.
Task level configuration
In some cases, you need to use a different toolchain for a specific task. Let’s say the library you develop has a specific code path depending on the Java version it runs on. You will want to make sure both code paths are exercised and so will run a set of tests with a different Java version. This scenario is supported as follows.
Head over to the documentation to learn more about it.
Further benefits of toolchain usage
In addition to the benefits we have discussed earlier, toolchains can help in more situations.
It was problematic for Gradle to build code on not yet released Java versions – like Java 16 at the time of writing – which may fail to run existing releases of Gradle – such as the current 6.7 release.
With toolchains support, Gradle 6.7 is perfectly capable of compiling and testing code with a not yet released language version. You only need to ask it to do it:
Additionally, the code may behave differently when built and run with different Java versions, potentially causing hard to diagnose issues.
Even without incompatibilities affecting the system behavior, using different Java versions to build the project on different machines can reduce build performance because of build cache misses.
Relaxing Java version constraints on Gradle
In addition to the benefits for build authors, this feature will have an impact on the development of Gradle itself. Up to now Gradle assumed that it would run with the same version of Java as required by your project. This means that Gradle has to be able to run with a set of Java versions spanning the needs of the projects using Gradle. With the release cadence of Java 5 to 8 this was probably acceptable. With the new Java release schedule, this is more problematic.
As of version 6.7, Gradle requires:
- Java 8 at the minimum to run a build,
- is built daily with 11
- and tested up to Java 15.
All of that requires quite a sophisticated CI setup and imposes constraints on Gradle core development. Features and APIs beyond Java 8 are not accessible to Gradle engineers for developing the tool for example.
Once toolchains are adopted in the community, we will eventually be able to be less conservative with Gradle’s runtime requirements. Gradle may then only run on relatively recent Java versions while supporting to build code for older Java versions through toolchains.
What’s next for toolchains?
In Gradle 6.7, the toolchain support is limited to the tasks known by the Java dedicated plugins:
Toolchain support for the Groovy and Scala plugins is planned to be added in one of the next Gradle releases.
We also hope that given the benefits of this feature for users, community plugin authors will leverage the toolchain support in their own tasks.
Related Posts
Different ways to configure java or JDK version in Gradle project
This tutorial talks about different ways of configuring the java version in Gradle projects.
In java projects, Source projects are compiled and generated class files.
In Gradle, For the java plugin, We need to provide the java version in build Gradle for compiling and generating class files.
Java installation is required for building the Gradle project and running the Gradle build.
How to configure source and target JDK version in gradle build
to compile files in java, we use the javac command and which has source and target arguments for the javac command.
javac Emp.java -source 1.9 -target 1.8
source tells the compiler to compile with a specific version target tells the compiler to support the lowest java version to support
In the above program, Emp.java code is compiled with the java 1.9 version, and generated class file has compatible with 1.8 or more, but not 1.7 or newer versions.
Does Gradle support this property? Yes, It supports the same approach with different properties.
It has sourceCompatibility and targetCompatibility properties.
To configure in build.gradle
sourceCompatibility = '1.10' targetCompatibility = '1.8'
sourceCompatibility uses the java version to compile java files targetCompatibility tells generate class supports minimum java version that has support
This option enables the running of all tasks with specific versions.
Suppose you want different versions for each task, you can configure the build script as follows
tasks.withType options.compilerArgs.addAll(arrayOf("--release", "12")) >
The above script tells us to use java version 12 to compile java files in a Gradle project.
How to install and configure the java version with gradle build?
By default, Gradle uses the java version from the JAVA_HOME environment variable path configured in the machine, and JAVA_HOME points to JDK installed on the machine.
For example, the machine is installed with the JDK 1.8 version and the Gradle project needs a java 11 version.
- install the java 11 version on the machine and it is straightforward
- Gradle project has a configuration to install the required Java version and configure.
How do you configure gradle build with java installation and configuration?
with Gradle 6.7 version, It has support for java toolchains
- It ignores the java version on the machine
- In the build file, configure the java version
- It installs JDK if not installed
- Gradle build runs with that version.
- No configuration required for sourceCompatibility and targetCompatibility properties
- First configure plugins for java-library
- next, configure the toolchain with the required java version
In the build.gradle file, configure the below code.
plugins id("java-library") // id("application") > java toolchain languageVersion.set(JavaLanguageVersion.of(12)) > >
- Installs java 12 versions from remote locations, Locations can be configurable
- check for valid installation
- All java related tasks use the java 12 version to compile and generate class files
- All test-related tasks use the java 12 version
- documentation relate tasks use the java 12 version.
It has the flexibility to configure the java version at the task level.
For example, Configure java Compilation requires 12 versions and test requires 15 versions.
tasks.register("extraTests") javaLauncher.set(javaToolchains.launcherFor languageVersion.set(JavaLanguageVersion.of(15)) >) >
Conclusion
In this tutorial, You learned different ways to configure the java version.
- using sourceCompatibility and targetCompatibility options in the build.gradle
- java toolchain support
With the above two options, You can choose to use the java version differently either at the project level or task level with examples.
How To Use Specific JDK Version For Gradle Build
Are you stuck or confused how to build a Java or Spring Boot project when your system has multiple versions of Java or JDK installed? I will show you how to use specific jdk version for gradle build.
Java version might be different in your classpath than what you want to use in your project and probably you might not have permission to change the environment variables’ value. Or you are working on multiple projects with different Java versions for those projects. Then you need to use specific Java version for building your project with Gradle build tool.
Problem Scenario
Let’s say your class path Java version shows as given below in the image:
Let’s say you are working on multiple projects where few of them require JDK version 1.8 or 8 but few other projects require JDK version 11.
The projects that require JDK 1.8, you can simply navigate to the project’s root directory in CLI and execute the command gradlew clean build or gradlew build to build the projects. The projects that require Jdk version 11, simply executing the same command from CLI, will fail to build, because class path knows about only Jdk version 1.8.
Solution
To solve this problem Gradle tool provides an option to pass the installed JDK’s home directory path. So, for example, you need to execute the command: gradlew build -Dorg.gradle.java.home=»jdk home path» , where jdk home path would be, for example, C:\Java\jdk-11.0.2. Note the path is up to installation directory’s root path only and it does not contain bin folder.
Therefore, the command will be gradlew build -Dorg.gradle.java.home=» C:\Java\jdk-11.0.2″ or if you want to clean the old build before running build again: gradlew clean build -Dorg.gradle.java.home=» C:\Java\jdk-11.0.2″ .
That’s all about how to use specific jdk version for gradle build.