Compile Java 8 Android library to be consumed in Java 7 - java

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.

Related

Support JAVA-8 Jar in Android 5 - React Native

Solution from Android Documentation is below
android {
defaultConfig {
// Required when setting minSdkVersion to 20 or lower
multiDexEnabled true
}
compileOptions {
// Flag to enable support for the new language APIs
coreLibraryDesugaringEnabled true
// Sets Java compatibility to Java 8
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.9'
}
This is working fine for Native android app, But this configuration is not working for React-Native app and throwing below error while building the app.
A problem occurred evaluating project ':app'.
Could not find method coreLibraryDesugaringEnabled() for arguments [true] on object of type com.android.build.gradle.internal.CompileOptions.
Half knowledge in always dangerous, and it happens here. As per the documentation above solution worked only for gradle version greater than 4. My gradle version was
classpath("com.android.tools.build:gradle:3.5.3")
I changed it to
classpath "com.android.tools.build:gradle:4.0.1"
Now it's working.

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

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 to use Realm database with Java 8 features

I am new to using Realm database for Android.
I modified my gradle files to include the Jack toolchain so that I could use Java 8 language features. I also modified the gradle files to install the Realm plugin. When I synced the project gradle files, I received the following error: Error:Could not find property 'options' on task ':app:compileDebugJavaWithJack'. The two modifications work fine on their own, but for some reason I cannot have both at the same time.
I would very much appreciate help on this matter.
It is not possible to use Jack compiler with Realm at the moment, because Jack does not support bytecode manipulation (Javassist / Transform API).
In order to use lambdas, it's easier for you to use Retrolambda instead for the time being.
buildscript {
//...
dependencies {
classpath "io.realm:realm-gradle-plugin:1.1.0"
classpath 'me.tatarka:gradle-retrolambda:3.2.5'
}
}
And
apply plugin: 'me.tatarka.retrolambda'
apply plugin: 'realm-android'
android {
...
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
Unfortunately Jack compiler and Realm can't play together right now. Please follow that topic. That one is also useful.

Error importing java.util.stream.Stream in Android Studio

I am using Java JDK version 1.8.0_60-b27 for both Netbeans and Android Studio. I could not import java.util.function.Consumer and java.util.stream.Stream packages in my Android Studio project. But I can import the same in my Netbeans Project. What is the reason?
In Google I/O 2016, they announced that Android now supports some features of Java 8, but not all the features.
Features like :
- Default and static interface methods
- Lambda expressions (also available on API level 23 and lower)
- Repeatable annotations
- Method References (also available on API level 23 and lower)
- Type Annotations (also available on API level 23 and lower)
Additionally, the following Java 8 language APIs are also available:
Reflection and language-related APIs:
java.lang.FunctionalInterface java.lang.annotation.Repeatable java.lang.reflect.Method.isDefault()
and Reflection APIs associated with repeatable annotations, such as AnnotatedElement.getAnnotationsByType(Class) Utility APIs: java.util.function java.util.stream
All what you should do is to use the new jack compiler, to do this you have just to add this to your gradle file build.gradle "module:app":
android {
...
defaultConfig {
...
jackOptions {
enabled true
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
Refrences
https://developer.android.com/guide/platform/j8-jack.html https://www.youtube.com/watch?v=B08iLAtS3AQ&feature=youtu.be&t=28m14s
Android only supports Java 7. Because of this you cannot use the Java Stream API introduced with Java 8. There exist some backports for this features, like
https://github.com/aNNiMON/Lightweight-Stream-API for Streams
or
https://github.com/orfjackal/retrolambda for Lambda-Expressions.

Categories

Resources