How to dynamically switch JDK when building Java in Gradle

Introduction

OpenJDK11 was released in September 2018. If you use Java for enterprise projects, you probably have JDK11. Also, I've heard some people who are already using JDK8 but want to adopt JDK11 for some new projects.

I'm using JDK8 this time, but when I started to verify with JDK11, I wondered what kind of build settings would be good if I wanted to support (build) both JDK8 and JDK11 in Gradle build. .. It should be noted that changes to the JDK, modification of the application due to version upgrade, tuning, etc. are necessary items, but they are excluded from this article. I just want to focus on how to dynamically switch the JDK at build time.

Settings

1. Specify parameters with sourceCompatibility, targetCompatibility of build.gradle

I think that the JDK version is often specified as a fixed value in build.gradle. (Or listed in gradle.properties)

The image is as follows.

build.gradle


...

sourceCompatibility = 1.8
targetCompatibility = 1.8

...

Or if you put the value in gradle.properties

build.gradle


...

sourceCompatibility = javaVersion
targetCompatibility = javaVersion

...

gradle.properties


...
javaVersion=1.8
...

It is an image.

I want to switch dynamically when the build is executed, so the definition of build.gradle is

build.gradle


...

sourceCompatibility = javaVersion
targetCompatibility = javaVersion

...

And define it as a variable.

2. Set the JDK version and JAVA_HOME in the parameters at build time

You can specify the parameter with -Pkey = value of gradle. You can use this to specify the JDK version at build time, such as gradle build -PjavaVersion = 1.11. You also need to specify the JDK used by Gradle. This can be specified with the ʻorg.gradle.java.home` parameter.

Therefore

gradle build -PjavaVersion=1.11 -Dorg.gradle.java.home="C:\java\11 --info"

Isn't it good to do like this?

Verification

Project structure

The project structure is as follows.

C:
└─src
    └─main
       ├─java
       │  └─sample
       │      └─gradle
       │          └─multiversion
       │              Sample.java
       └─resources

build.gradle


plugins {
    id 'java-library'
}

repositories {
    jcenter()
}

dependencies {
}

sourceCompatibility = javaVersion
targetCompatibility = javaVersion

Build & verify with JDK11

Build with JDK11.

>gradle build -PjavaVersion=1.11 -Dorg.gradle.java.home="C:\java\11"

BUILD SUCCESSFUL in 1s
2 actionable tasks: 2 executed

Check the version built with javap -v for the actually compiled class file.

As you can see from the execution result below, you can see that it is built with major version: 55 and JDK11.

C:\workspace\sample-gradle-multiversion>javap -v build\classes\java\main\sample\gradle\multiversion\Sample.class
Classfile /C:/workspace/sample-gradle-multiversion/build/classes/java/main/sample/gradle/multiversion/Sample.class
  Last modified 2019/07/12; size 576 bytes
  MD5 checksum 580cd2384cb91a31c14e09339617ba75
  Compiled from "Sample.java"
public class sample.gradle.multiversion.Sample
  minor version: 0
  major version: 55
  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
  this_class: #5                          // sample/gradle/multiversion/Sample
  super_class: #6                         // java/lang/Object
  interfaces: 0, fields: 0, methods: 2, attributes: 1
Constant pool:
   #1 = Methodref          #6.#20         // java/lang/Object."<init>":()V
   #2 = Fieldref           #21.#22        // java/lang/System.out:Ljava/io/PrintStream;
   #3 = String             #23            // Hello world.
   #4 = Methodref          #24.#25        // java/io/PrintStream.println:(Ljava/lang/String;)V
   #5 = Class              #26            // sample/gradle/multiversion/Sample
   #6 = Class              #27            // java/lang/Object
   #7 = Utf8               <init>
   #8 = Utf8               ()V
   #9 = Utf8               Code
  #10 = Utf8               LineNumberTable
  #11 = Utf8               LocalVariableTable
  #12 = Utf8               this
  #13 = Utf8               Lsample/gradle/multiversion/Sample;
  #14 = Utf8               main
  #15 = Utf8               ([Ljava/lang/String;)V
  #16 = Utf8               args
  #17 = Utf8               [Ljava/lang/String;
  #18 = Utf8               SourceFile
  #19 = Utf8               Sample.java
  #20 = NameAndType        #7:#8          // "<init>":()V
  #21 = Class              #28            // java/lang/System
  #22 = NameAndType        #29:#30        // out:Ljava/io/PrintStream;
  #23 = Utf8               Hello world.
  #24 = Class              #31            // java/io/PrintStream
  #25 = NameAndType        #32:#33        // println:(Ljava/lang/String;)V
  #26 = Utf8               sample/gradle/multiversion/Sample
  #27 = Utf8               java/lang/Object
  #28 = Utf8               java/lang/System
  #29 = Utf8               out
  #30 = Utf8               Ljava/io/PrintStream;
  #31 = Utf8               java/io/PrintStream
  #32 = Utf8               println
  #33 = Utf8               (Ljava/lang/String;)V
{
  public sample.gradle.multiversion.Sample();
    descriptor: ()V
    flags: (0x0001) ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         4: return
      LineNumberTable:
        line 6: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   Lsample/gradle/multiversion/Sample;

  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=1, args_size=1
         0: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
         3: ldc           #3                  // String Hello world.
         5: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
         8: return
      LineNumberTable:
        line 10: 0
        line 12: 8
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       9     0  args   [Ljava/lang/String;
}
SourceFile: "Sample.java"

Keep gradle clean to remove the class files built with JDK 11.

C:\workspace\sample-gradle-multiversion>gradle clean -PjavaVersion=1.11

BUILD SUCCESSFUL in 1s
1 actionable task: 1 executed

Build & verify with JDK8

Then build with JDK8.

C:\workspace\sample-gradle-multiversion>gradle build -PjavaVersion=1.8 -Dorg.gradle.java.home="C:\java\8"

BUILD SUCCESSFUL in 1s
2 actionable tasks: 2 executed

Check the class file. You can see that it was built with major version: 52 and JDK8.

C:\workspace\sample-gradle-multiversion>javap -v build\classes\java\main\sample\gradle\multiversion\Sample.class
Classfile /C:/workspace/sample-gradle-multiversion/build/classes/java/main/sample/gradle/multiversion/Sample.class
  Last modified 2019/07/12; size 576 bytes
  MD5 checksum ea23dd24700da60b773d93f8ff2f9d77
  Compiled from "Sample.java"
public class sample.gradle.multiversion.Sample
  minor version: 0
  major version: 52
  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
  this_class: #5                          // sample/gradle/multiversion/Sample
  super_class: #6                         // java/lang/Object
  interfaces: 0, fields: 0, methods: 2, attributes: 1
Constant pool:
   #1 = Methodref          #6.#20         // java/lang/Object."<init>":()V
   #2 = Fieldref           #21.#22        // java/lang/System.out:Ljava/io/PrintStream;
   #3 = String             #23            // Hello world.
   #4 = Methodref          #24.#25        // java/io/PrintStream.println:(Ljava/lang/String;)V
   #5 = Class              #26            // sample/gradle/multiversion/Sample
   #6 = Class              #27            // java/lang/Object
   #7 = Utf8               <init>
   #8 = Utf8               ()V
   #9 = Utf8               Code
  #10 = Utf8               LineNumberTable
  #11 = Utf8               LocalVariableTable
  #12 = Utf8               this
  #13 = Utf8               Lsample/gradle/multiversion/Sample;
  #14 = Utf8               main
  #15 = Utf8               ([Ljava/lang/String;)V
  #16 = Utf8               args
  #17 = Utf8               [Ljava/lang/String;
  #18 = Utf8               SourceFile
  #19 = Utf8               Sample.java
  #20 = NameAndType        #7:#8          // "<init>":()V
  #21 = Class              #28            // java/lang/System
  #22 = NameAndType        #29:#30        // out:Ljava/io/PrintStream;
  #23 = Utf8               Hello world.
  #24 = Class              #31            // java/io/PrintStream
  #25 = NameAndType        #32:#33        // println:(Ljava/lang/String;)V
  #26 = Utf8               sample/gradle/multiversion/Sample
  #27 = Utf8               java/lang/Object
  #28 = Utf8               java/lang/System
  #29 = Utf8               out
  #30 = Utf8               Ljava/io/PrintStream;
  #31 = Utf8               java/io/PrintStream
  #32 = Utf8               println
  #33 = Utf8               (Ljava/lang/String;)V
{
  public sample.gradle.multiversion.Sample();
    descriptor: ()V
    flags: (0x0001) ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         4: return
      LineNumberTable:
        line 6: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   Lsample/gradle/multiversion/Sample;

  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=1, args_size=1
         0: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
         3: ldc           #3                  // String Hello world.
         5: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
         8: return
      LineNumberTable:
        line 10: 0
        line 12: 8
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       9     0  args   [Ljava/lang/String;
}
SourceFile: "Sample.java"

Conclusion

  1. Defined as a variable in sourceCompatibility, targetCompatibility of build.gradle
  2. When building Gradle, set the JDK version with the parameter -P and JAVA_HOME with the -Dorg.gradle.java.home

Recommended Posts

How to dynamically switch JDK when building Java in Gradle
[Java] How to switch from open jdk to oracle jdk
When you want to dynamically replace Annotation in Java8
How to run Ant in Gradle
How to learn JAVA in 7 days
How to use classes in Java?
How to name variables in Java
How to switch Java in the OpenJDK era on Mac
How to dynamically switch between FIN and RST in Netty
How to concatenate strings in java
How to switch Java version with direnv in terminal on Mac
How to solve the unknown error when using slf4j in Java
How to implement date calculation in Java
How to implement Kalman filter in Java
Multilingual Locale in Java How to use Locale
How to do base conversion in Java
How to switch Java versions on Mac
How to implement coding conventions in Java
How to embed Janus Graph in Java
How to get the date in java
How to switch between multiple Java versions
How to find the total number of pages when paging in Java
How to pass a proxy when throwing REST over SSL in Java
How to display a web page in Java
How to get Class from Element in Java
How to hide null fields in response in Java
How to Install Oracle JDK 1.8 in Ubuntu 18.04 LTS?
[Java] How to substitute Model Mapper in Jackson
How to solve an Expression Problem in Java
How to log in automatically when Ubuntu restarts
How to write Java String # getBytes in Kotlin?
How to use Gradle
How to call functions in bulk with Java reflection
How to switch Tomcat context.xml with WTP in Eclipse
How to create a data URI (base64) in Java
Organized how to interact with the JDK in stages
How to change from Oracle Java 8 to Adopt Open JDK 9
How to generate / verify ID token in Java Memo
What I learned when building a server in Java
How to convert A to a and a to A using AND and OR in Java
How to convert a file to a byte array in Java
How to Git manage Java EE projects in Eclipse
Summary of how to implement default arguments in Java
How to put old Java (8 series) in macOS 10.15 Catalina
Notes on how to use regular expressions in Java
How to get the class name of the argument of LoggerFactory.getLogger when using SLF4J in Java
Summary of how to use the proxy set in IE when connecting with Java
How to get the class name / method name running in Java
[Java] How to use Map
How to read your own YAML file (*****. Yml) in Java
[Java] How to use Map
How to uninstall Java 8 (Mac)
Java conditional branching: How to create and study switch statements
Java --How to make JTable
How to use JSON data in WebSocket communication (Java, JavaScript)
How to set chrony when the time shifts in CentOS7
How to use java Optional
Memo: [Java] How to check groupId etc. described in pom.xml
How to minimize Java images
How to write java comments
How to use java class