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

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
} }

Related

Gradle using 2 different JDK

I would like use some features from Java 9 and 10 in my PC java application which has common code with android app.
When I use jdk 10 or jdk 9 android application is building, but it doesn't launch(it is throwing a lots of errors). When I use jdk 8 for whole project everything is working correctly without any error. When I manually build project using 2 different jdk everything is working fine.
I tried set targetCompability and sourceCompability for android application for JavaVersion.Version_1_7 but it doesn't help. I tried use different jdks for java 9 and java 10 but it doesn't help with this problem.
I would like build android application and common component with jdk8 and other components with jdk10. Is it possible to force gradle to use different jdk for specific project without using external tools like bash?
My project structure looks like:
build.gradle
common-component(jdk8)/build.gradle
PC(jdk 10)/build.gradle
device-Android(jdk 8)/build.gradle
I found workaround. It works fine with gradle 4.7(Java 10 support was added in this release). This hack/workaround requires to launch project using lower JDK like Oracle JDK 8 or OpenJDK. We can build some components using higher version of JDK, but we can't build JDK project with JDK10 and then use it with JDK8 if we specify targetcompablility higher than 1.8. It will work only for java project and probably it won't work for android plugin and other JVM languages.
Part of build.gradle for PC application :
project (':pc-client') {
dependencies {
compile project(':net-default')
testcompile JUNIT
}
compileJava {
options.fork = true
options.forkOptions.javaHome = file('/usr/lib/jvm/java-10-oracle')
targetCompatibility = 1.10
sourceCompatibility = 1.10
}
compileTestJava {
options.fork = true
options.forkOptions.javaHome = file('/usr/lib/jvm/java-10-oracle')
targetCompatibility = 1.10
sourceCompatibility = 1.10
}
}

Compile Java 8 Android library to be consumed in Java 7

Let's say I am making an Android library (to be distributed as a .aar) and I want to use Java 8 language features in my internal library code. Basic stuff like lambdas, etc.
In my experience, if I then assemble and publish this library any developer that relies up on it will get errors in build unless they add this to their build.gradle:
android {
// ...
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
Is there any way to compile my library so that consumers don't have to do this? Assume that the public API surface of the library does not contain any Java 8 specific features.

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.

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

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)
}

Categories

Resources