Generic Top

Get started with Spring 5 and Spring Boot 2, through the Learn Spring course:

>> CHECK OUT THE COURSE

1. Overview

In this article, we'll look at the difference between sourceCompatbility and targetCompatibility Java configurations as well as their usage in Gradle.

You can check our Introduction to Gradle article to learn more about the basics.

2. Handling Versions in Java

When we compile a Java program using javac, we can provide compilation options for version handling. There are two options available:

  • -source with values that match the Java versions, up to the JDK we are using for compilation (for example, 1.8 for JDK8). The version value we provide will restrict the language features that we can use in our source code to its respective Java version.
  • -target is similar but controls the version of the generated class files. This means that the version value we provide will be the lowest Java version our program can run on.

For example:

javac HelloWorld.java -source 1.6 -target 1.8

This will generate a class file that requires Java 8 or above to run. Additionally, the source code cannot contain lambda expressions or any feature not available in Java 6.

3. Handling Versions With Gradle

Gradle, along with the Java plugin, lets us set the source and target options with the sourceCompatibility and targetCompatibility configurations of the java task. Similarly, we use the same values as we do with javac.

Let's set up the build.gradle file:

plugins {
    id 'java'
}

group 'com.baeldung'

java {
    sourceCompatibility = "1.6"
    targetCompatibility = "1.8"
}

4. HelloWorldApp Example Compilation

We can create a Hello World! console app and demonstrate the functionality by building it using the above script.

Let's create a very simple class:

public class HelloWorldApp {
    public static void main(String[] args) {
        System.out.println("Hello World!");
    }
}

When we build it using the gradle build command, Gradle will generate a class file with the name HelloWorldApp.class.

We can use the javap command-line tool that is packaged with Java to check the generated bytecode version of this class file:

javap -verbose HelloWorldApp.class

This prints a lot of information, but in the first few lines, we can see:

public class com.baeldung.helloworld.HelloWorldApp
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_SUPER

The major version field has the value 52, which is the version number for Java 8 class files. This means that our HelloWorldApp.class can only run using Java 8 and above.

To test the sourceCompatibility configuration, we can change our source code and introduce a feature that is not available in Java 6.

Let's use a lambda expression:

public class HelloWorldApp {

    public static void main(String[] args) {
        Runnable helloLambda = () -> {
            System.out.println("Hello World!");
        }
        helloLambda.run();
    }

}

If we try to build our code with Gradle, we'll see a compilation error:

error: lambda expressions are not supported in -source 1.6

The -source option, which is the Java equivalent of the sourceCompatibility Gradle configuration, prevents our code from compiling. Basically, it protects us from using higher version features by mistake if we don't want to introduce them – for example, we may want our app to be able to run on Java 6 runtimes as well.

5. Conclusion

In this article, we explained how to use the -source and -target compilation options to handle the versions of our Java source code and the target runtime. In addition, we learned how these options map to Gradle's sourceCompatbility and targetCompatibility configurations with the Java plugin and demonstrated their functionality in practice.

As always, the source code for this article is available over on GitHub.

Generic bottom

Get started with Spring 5 and Spring Boot 2, through the Learn Spring course:

>> CHECK OUT THE COURSE
Generic footer banner
Comments are closed on this article!