How do I specify the required Java version in a Gradle build? - java

I would like to set the required Java version (e.g. 7 or 8) in my Gradle build file without having to specify the actual path to a local JDK installation.
Is this possible?

This feature was just added to Gradle 6.7 as Java toolchains:
// build.gradle.kts
plugins {
id("java-library") // or id("application")
}
java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(11))
}
}
With this in place Gradle will automatically download & use the appropriate JDK (using AdoptOpenJDK by default) for the specified Java version.

TLDR;
Thanks #franklin-yu "targetCompatibility = '1.7' -> your user can compile with 8 and run with 7."
See Gradle, "sourceCompatibility" vs "targetCompatibility"?
targetCompatibility = '1.7' does the trick for e.g. Java 7
Use sourceCompatibility = '1.7' for the language level

You can try this:
java {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
tasks.withType<JavaCompile> {
options.compilerArgs.addAll(arrayOf("--release", "8"))
}
This will also give JDK compliance to you. You can also see the following related issues:
Gradle: [Java 9] Add convenience method for -release compiler argument
Eclipse Plug-ins for Gradle: JDK API compatibility should match the sourceCompatibility option.

In the build.gradle file, add the following two lines:
sourceCompatibility = '1.8'
targetCompatibility = '1.8'
The targetCompatibility defines the generated JVM bytecode version (this is the version that users of your application need). The sourceCompatibility defines which source code constructs are allowed (e.g. you need Java 1.8 or higher to use lambda expressions in source code).
Source

Based on the answer of CletusW. In windows 10, it seems that the new installed Java will not be chosen automatically, so I check it manually.
apply plugin: 'java'
java.toolchain.languageVersion = JavaLanguageVersion.of(15) // auto install
// check JDK version
if (!System.getProperty("java.home").contains(java.toolchain.languageVersion.get().toString())) {
def msg = ('JDK in this project: ' + System.getProperty('java.home') + '\n' +
'In this project, you should use JDK-' + java.toolchain.languageVersion.get())
throw new GradleException(msg)
}

Related

'<>' operator is not allowed for source level below 1.7 in jsp

Following is the error message while running build command in gradle. I am migrating from tomcat 7 to Tomcat 9.
_jspx_imports_classes = new java.util.HashSet<>();
^^^^^^^^^^^^^^^^^
'<>' operator is not allowed for source level below 1.7
I am using JDK 1.8 and gradle for build the code.
Today i fixed my issue
subprojects {
apply plugin: 'com.parag.gradle.buildinfo'
if(! assemblyProjects.contains(it)) {
// setup source and target compatibility for jsp and add default dependencies
plugins.withId('com.parag.gradle') {
tasks.withType(<taskType>) {
sourceCompatibility = 1.8
targetCompatibility = 1.8
jspPackage = "org.apache.jsp.${project.name}"
}
dependencies {
compile 'org.apache.tomcat:tomcat-jsp-api'
}
}
dependencies {
compile 'org.apache.tomcat:tomcat-el-api'
// compile 'javax.servlet:javax.servlet-api'
compile 'org.apache.tomcat:tomcat-servlet-api'
}
}
}

How do I know what to set sourceCompatibility vs targetCompatibility to?

according to MoPub Docs I should add this to my gradle file, but my question is what do I pick for sourceCompatibility and target compatibility, it seems like target Compatibility has to be set to 1_8 or else it will not build. But what is the difference if I leave sourceCompatibility to 1_7 vs 1_8 is there a way to know which one my project uses, sourceCompatibility builds the app fine with either one set I would just like to know what is the difference between the 2 and if I actually do need to set it to 1 of them instead of the other also I've read that gradle uses the java version which is on our machine and mine is 1.8.0 so why do I have to explicitly declare VERSION_1_8 ?
on java docs it states "Generates class files that target a specified release of the virtual machine. Class files will run on the specified target and on later releases, but not on earlier releases of the JVM. Valid targets are 1.1, 1.2, 1.3, 1.4, 1.5 (also 5), 1.6 (also 6), 1.7 (also 7), and 1.8 (also 8)." but java 1.7&1.8 not available on android 4.1 and it still runs on android 4.1 when I set java version to 1.7 or 1.8 how is this possible ?
android {
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_8
} }

Configure Gradle for Kotlin with Java 1.7

Ok, so I'm new to Gradle and Kotlin and I am having a hard time understanding how things glue together here...
I need to configure a project that should run on Java 7 (client limitations -_-) and I want to use Kotlin with it.
Right now I have the following build.gradle file that is working but I want to ask a few things that I couldn't find anywhere else:
buildscript {
ext {
springBootVersion = '1.5.15.RELEASE'
kotlin_version = '1.1.1'
}
repositories {
mavenCentral()
}
dependencies {
classpath "org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
apply plugin: 'java'
apply plugin: 'kotlin'
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'
group = 'com.springkotlin'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.7
targetCompatibility = 1.7
repositories {
mavenCentral()
}
dependencies {
compile('org.springframework.boot:spring-boot-starter-data-rest')
compile('org.springframework.boot:spring-boot-starter-security')
compile('com.onelogin:java-saml:2.3.0')
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk7"
runtime('org.springframework.boot:spring-boot-devtools')
testCompile('org.springframework.boot:spring-boot-starter-test')
testCompile('org.springframework.security:spring-security-test')
testCompile group: 'javax.inject', name: 'javax.inject', version: '1'
}
compileKotlin {
kotlinOptions {
jvmTarget = "1.6"
}
}
Now the questions:
I have tried using kotlin_version = '1.2.70' (released last few days!) and I got the error KotlinPluginWrapper : Unsupported major.minor version 52.0. I'm guessing then this is due to Kotlin 1.2.X only being able to "compile" (is that the word?) with Java 8+. Is that right? Is 1.1.1 the right version to use here or is there a way to use 1.2.70 that would work with Java 7? Will I be missing a lot of stuff for using it?
I want to understand the 3 kotlin stuff I had to setup on the script. Correct me please:
kotlin-gradle-plugin: Is used to define which version of Kotlin I will be using(?)
apply plugin: 'kotlin': As far as I know from Gradle, this should add tasks to work with Kotlin but running gradle tasks I didn't see anything different... So what is it really for?
kotlin-stdlib-jdk7: I'm guessing this is Kotlin lib of functions, classes, etc. What I don't understand though is the difference between stdlib and stdlib-jdk7. The documentation says it contains "addition extension functions". But which ones? Also, should I define a version for this guy? Or does it automatically picks up the kotlin-gradle-plugin version?
Thanks in advance,
Currently the compiler of the Kotlin language requires JDK 8 to run. A project compiled with Kotlin can target any Java starting from Java 6.
A recipe to setup Gradle build of a project that runs on Java 7 is following:
run Gradle with Java 8 or later
for all Kotlin compile tasks
specify jvmTarget = "1.6" in kotlinOptions
specify path to JDK 7 in jdkHome in kotlinOptions
if your project contains java code specify sourceCompatibility, targetCompatibility convention properties of the Java plugin
specify the following options of all java compile tasks:
isFork = true
forkOptions.javaHome = "<path to JDK 7>"
for all Test tasks specify executable as "<path to JDK 7>/bin/java"
The full sample:
sourceCompatibility = 1.7
targetCompatibility = 1.7
def JDK_7 = System.getenv("JDK_7") // or some other way to get path to JDK 7 installation
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile) {
kotlinOptions {
jvmTarget = "1.6"
jdkHome = JDK_7
}
}
tasks.withType(JavaCompile) {
options.fork = true
options.forkOptions.javaHome = file(JDK_7)
}
test {
executable = "$JDK_7/bin/java"
}
Kotlin can target either Java 6 or Java 8 and I don't think this has changed. However, it is quite likely that the default has changed from Java 6 to Java 8, so try as suggested here:
compileKotlin {
sourceCompatibility = JavaVersion.VERSION_1_6
targetCompatibility = JavaVersion.VERSION_1_6
kotlinOptions {
jvmTarget = "1.6"
apiVersion = "1.2"
languageVersion = "1.2"
}
}
The version of kotlin-gradle-plugin is the version of the Kotlin compiler used to compile your code. The version of the stdlib is the version of your runtime library. It is highly recommended to use the same version here.
The apply plugin: kotlin adds some tasks under the hood - just continue using the java tasks like gradle assemble, gradle build and gradle run as they will invoke the kotlin specific tasks
kotlin-stdlib-jdk7 adds very little value - unless you use features of the java library that were introduced in java 7 and that have extensions from Kotlin's stdlib, you'll be fine to just use the default stdlib (which targets Java 6 and is a dependency of kotlin-stdlib-jdk7 anyways).

Java 1.7 compatibility for a library in android studio

I want to use this library in my android studio project but when I add it into project using gradle it show the following error
Error:Error converting bytecode to dex: Cause: Dex cannot parse version 52 byte code. This is caused by library dependencies that have been compiled using Java 8 or above. If you are using the 'java' gradle plugin in a library submodule add targetCompatibility = '1.7' sourceCompatibility = '1.7' to that submodule's build.gradle file.
It seems it is because of java 1.7 compatablility but I have no idea how to fix it. Android studio suggests to add targetCompatibility = '1.7' sourceCompatibility = '1.7' to that submodule's build.gradle but how can I add it into gradles dependencies section?
Version 52 is actually Java 8.
The library was compiled without Java 7 compatibility, so it cannot be used if you are targeting Java 7 or lower.
I see that there's an open issue about it on their GitHub. It might be a problem with this versions only, so you might try using a previous version until they fix the issue.
You should use VERSION_1_8 instead of VERSION_1_7
Install JDK 1.8
You should add this
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
FYI
Before use 1_8 please read Use Java 8 Language
To enable Java 8 language features and Jack for your project, enter the following in your module-level build.gradle file:
android {
...
defaultConfig {
...
jackOptions {
enabled true
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
Clean-Rebuild and RUN

How do I set source and target compatability differently for different source sets in gradle

I have a project that has two source trees (client and main). The client needs to be compiled to Java 1.7 while main contains Java 1.8 constructs. I have the following gradle source set defined:
sourceSets {
main {
java {
srcDir "src/main/java"
srcDir "src/client/java"
}
}
compileMainJava {
sourceCompatibility = "1.8"
targetCompatibility = "1.8"
}
client {
java {
srcDir "src/client/java"
}
}
compileClientJava {
sourceCompatibility = "1.7"
targetCompatibility = "1.7"
}
}
However, the main source set is compiled with 1.7 apparently since I get this
:compileJavawarning: [options] bootstrap class path not set in conjunction with -source 1.7
C:\dev\eclipse-ws\generic\IoT-Sound\src\main\java\com\ibm\watson\iot\sound\feature\mfcc\MFCCFeatureExtractor.java:129: error: method references are not supported in -source 1.7
double[] x = Stream.of(xDataBoxed).mapToDouble(Double::doubleValue).toArray();
(use -source 8 or higher to enable method references)
If I comment out the compileMainJava element, then it builds both successfully and seems to compile the client to 1.7 since i get the same warning for compileClientJava (without errors). I guess this is because I'm using 1.8 jdk, but would like to add these attributes anyway.
So, how do i get main compatibility set to 1.8 and client to 1.7? Thanks.
You won't be able to have two language versions in the same project. That said you could have other modules with different Java versions.
In this case you probably want 3 modules
:client
:main
:common
Now if you want the project(':client') to be Java 7 you can set it in client/build.gradle
compileJava {
sourceCompatibility = JavaVersion.VERSION_1_7
targetCompatibility = JavaVersion.VERSION_1_7
}
Then define your project(':main') to be Java 8 in the main/build.gradle
compileJava {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
Just be sure you use Java 7 in the project(':common') or the client won't know how to read the java 8 bytecode generated by common.

Categories

Resources