Gradle, "sourceCompatibility" vs "targetCompatibility"?
GradleJavaGradle Problem Overview
What is the relationship/difference between sourceCompatibility
and targetCompatibility
? What happens when they are set to different values?
According to Gradle documentation:
sourceCompatibility
is "Java version compatibility to use when compiling Java source."
targetCompatibility
is "Java version to generate classes for."
My understanding is that targetCompatibility
will generate java bytecode that is compatible with a specific version of Java, is this a subset of the functionality of sourceCompatibility
?
Gradle Solutions
Solution 1 - Gradle
targetCompatibility
and sourceCompatibility
maps to -target release
and -source release
in javac. Source is basically the source language level and target is the level of the bytecode that is generated.
More details can be found in the javac the cross compilation section.
Solution 2 - Gradle
Be careful when you use these; we've been bitten by people making assumptions.
Just because you use sourceCompability (or targetCompatibility) of 1.5 doesn't mean you can always compile your code with JDK 1.6 and expect it to work under JDK 1.5. The issue is the available libraries.
If your code happens to call some method that is only available in JDK 1.6 it will still compile with the various Compatibility options for the target VM. But when you run it, it will fail because the offending method is not present (you'll get a MethodNotFoundException or ClassNotFoundException).
For this reason, I always compare the Compatibility setting to the actual Java version I'm building under. If they don't match, I fail the build.
Solution 3 - Gradle
sourceCompatibility = specifies that version of the Java programming language be used to compile .java files. e.g sourceCompatibility 1.6 =specifies that version 1.6 of the Java programming language be used to compile .java files.
By default sourceCompatibility = "version of the current JVM in use" and targetCompatibility = sourceCompatibility
targetCompatibility = The option ensures that the generated class files will be compatible with VMs specified by targetCompatibility . Note that in most cases, the value of the -target option is the value of the -source option; in that case, you can omit the -target option.
Class files will run on the target specified by targetCompatibility and on later versions, but not on earlier versions of the VM
Solution 4 - Gradle
In my opinion, “sourceCompatibility” means the what feature you can use in your source code.For example,if you set sourceCompatibility to 1.7, then you can't use lambda expression which a new feature in java 8 even though you jdk version is 1.8.
As for “targetCompatibility”, it means which version of jre the generated class file can be run on, if you set it to 1.8,it may not run successfully on jdk 1.7, but it can usually run on higher version of jdk.
Solution 5 - Gradle
These are the flags for the javac command.
javac [options] [sourcefiles]
Options:
...
-source release - Specifies the version of source code accepted.
...
-target release - Generates class files for a specific VM version.
...
In other words: you write a code in a source
version and compile your classes to the target
VM version. In order to run it e.g. on other workstation with older java version.
According to: https://docs.oracle.com/en/java/javase/11/tools/javac.html