How the achieve desugaring in android gradle builds? - java

I'm developing an app that needs to run on phones with Android API 19+. In talks with management to see if we can drop support for older versions of Android, but it seems almost certain we can't live with 26+ only.
Recently there has appeared a need to use a library that uses some Java 1.8 features, and those fail to dex.
I had previously thought that automatic "desugaring" had been enabled when building/dexing with gradle for a while now, and issues like these would be "automagically" solved by converting the unsupported-in-1.7 opcodes to functionally equivalent 1.7 opcode blobs.
But my builds are failing with
"Private interface methods are only supported starting with Android N (--min-api 24)"
and similar error messages (as I said, API level 26 is the largest on I see), and:
"Failed to transform artifact '...' to match attributes {artifactType=android-dex, dexing-enable-desugaring=false, dexing-is-debuggable=false, dexing-min-sdk=1}"
As you can see, dexing seems to be happening with "dexing-enable-desugaring=false" and "dexing-min-sdk=1", and I'd like to change those. I've been searching for a way to set those for quite a while now, and can't seem to find a way to tell gradle to pass the right parameters to the dexer.
Here are the relevant snippets of configuration files:
gradle.properties:
androidBuildToolsVersion=28.0.3
androidCompileSdkVersion=28
gradle-wrapper.properties:
distributionUrl = https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
build.gradle:
buildscript {
repositories {
jcenter()
mavenCentral()
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.0'
classpath 'com.google.gms:google-services:3.0.0'
}
}
allprojects {
repositories {
jcenter()
google()
}
}
apply plugin: 'com.android.application'
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:23.0.1'
compile 'com.android.support:mediarouter-v7:23.0.1'
compile 'com.google.android.gms:play-services-analytics:10.0.0'
compile 'com.google.android.gms:play-services-cast:10.0.0'
compile 'com.google.android.gms:play-services-location:10.0.0'
compile 'com.google.firebase:firebase-core:10.0.1'
compile 'org.bouncycastle:bcpkix-jdk15on:1.60'
compile 'org.bouncycastle:bcprov-jdk15on:1.60'
...
}
apply plugin: 'com.google.gms.google-services'
android {
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
compileSdkVersion androidCompileSdkVersion.toInteger()
buildToolsVersion androidBuildToolsVersion
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
...
}
}
defaultConfig.applicationId = "..."
}
Any suggestions?
Also, worth noting, this is not a "pure" android / Gradle project, there is native code involved, and a build system that I don't have good control over, that runs Gradle as a step in the build process. If there are multiple ways to configure the dexer parameters, I'd prefer something that requires modifying build.gradle, as that is the only thing I have direct control over, inserting something into gradle.properties would require hacking the build system in ways I'd rather avoid, but I'll take it if that's the only way to do it.

Related

Android Studio - Error Module not specified

i'm a newbie to Android/Java development and purchased a book Java Programming for Android Developers For Dummies, 2nd Edition.
This comes with a code samples section http://users.drew.edu/bburd/Java4Android/ (chapter 02_01) I understand the book is a few years old hence so the code samples will be. However, i'm having massive problems getting the code samples to run on Android Studio 4.1.2.
I can import the project and sync the Gradle files. When I do it appears with a green tick at the bottom. Oddly it says failed next to that with the following message.
Gradle sync failed: Unsupported method: SyncIssue.getMultiLineMessage().
The version of Gradle you connect to does not support that method.
To resolve the problem you can change/upgrade the target version of Gradle you connect to.
Alternatively, you can ignore this exception and read other information from the model.
Consult IDE log for more details (Help | Show Log) (1 s 443 ms)
My build.gradle file is as follows
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.2.2'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
Also if I try and run the project I see this screen
I've read many posts with similar issues and worked through various fixes. None seemed to work so can anyone shed any light on what's happening please? I've also downloaded android studio on 3 different PC's incase its a bug of some sort.
Thank you
I should say the files in there are very outdated, and you will have very hard time, with every project. But if you still want to build the project here are a few things you can do.
look for the file gradle-wrapper.properties and update it with this
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip
Then move to project level build.gradle file (there are two one inside app directory and one on the root directory, use the root directory)
buildscript {
repositories {
jcenter()
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:4.1.2'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
google()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
Then move to app level build.gradle and update it with this
apply plugin: 'com.android.application'
android {
compileSdkVersion 30
defaultConfig {
applicationId "com.allyourcode.a02_01"
minSdkVersion 15
targetSdkVersion 30
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
androidTestImplementation('com.android.support.test.espresso:espresso-core:3.0.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:2.0.4'
testImplementation 'junit:junit:4.13.1'
}
And then sync the project and let Android studio do its magic.
As the stack traces say, you should upgrade your Gradle version. You are using an "old" book where the samples have been build with an old version of Android Studio that supports well that old version of Gradle. But 4.1 is a recent version and does not support well many old Gradle features.

getting red line in files after upgrading to gradle 4.4 and gradle build tools version 3.1.2

The Android studio ask me to update the gradle version to 4.4 and gradle build tool version to 3.1.2.
After the update, The whole android studio shows red lines in file, when I hover my cursor on these error it says "cannot resolve symbol" but compiles with no error i.e., build is successful.Click here to see red lines in java files
and Here are the gradle app and project files.
//Build.gradle(project)
//Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
maven {
url 'https://maven.fabric.io/public'
}
jcenter()
maven {
url 'https://maven.google.com/'
name 'Google'
}
}
dependencies {
classpath 'com.android.tools.build:gradle:3.1.2'
classpath 'com.google.gms:google-services:3.2.0'
classpath 'io.fabric.tools:gradle:1.25.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
maven {
url 'https://maven.google.com/'
}
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
and
//build.gradle(module:app)
apply plugin: 'com.android.application'
android {
compileSdkVersion 27
buildToolsVersion '27.0.3'
defaultConfig {
applicationId "com.developers.paras.droidwatch"
minSdkVersion 19
targetSdkVersion 27
versionCode 9
versionName "9.0"
multiDexEnabled true
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled true
shrinkResources true
android.defaultConfig.vectorDrawables.useSupportLibrary = true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:27.1.1'
compile 'com.android.support:customtabs:27.1.1'
compile 'com.android.support.constraint:constraint-layout:1.1.0'
compile 'com.android.support:design:27.1.1'
compile 'com.android.support:support-v4:27.1.1'
compile 'com.google.android.gms:play-services-ads:15.0.1'
compile 'com.google.firebase:firebase-core:15.0.2'
compile 'com.crashlytics.sdk.android:crashlytics:2.9.2'
testCompile 'junit:junit:4.12'
}
apply plugin: 'com.google.gms.google-services'
apply plugin: 'io.fabric'
Things I have already tried.
Clean and Rebuild.
Invalidate Cache and Restart.
Updating gradle version to 4.9.
Setting local gradle for the project.
See my gradle logs here https://drive.google.com/open?id=18bFZdkWX4AFPfpmfjvN1t80WpVRpiHWs
See even release build is generated after these errors. Release apk generated
Update : Recently after Reinstalling Studio, I've created a new project and everything works fine. No errors for "cannot resolve symbol".
not the most graceful solution in the world but deleting and re-cloning the project was the fastest way to resolve this for me.
if you're not using git... well. now is a good time to start.
I tried deleting and re-syncing all the various config files and it didn't do anything.
I got into similar situation: upgraded Gradle to 4.4, then opened a former porject which had been built with Gradle 3.1.2.
Android Studio noticed it and generously offered:
To take advantage of all the latest features (such as Instant Run), improvements and security fixes, we strongly recommend that you update the Android Gradle plugin to version 3.1.2 and Gradle to version 4.4.
When I choose to update, I got the red underlines showing errors everywhere in MainActivity.java, however the project was building and runnig perfectly.
I also tried to rebuild and to invalidate cache & restart, but had no success.
For me, editing the build.gradle (module:app) file helped.
When I modified both compileSdkVersion and targetSdkVersion to the latest (27) and changed the version number of line implementation 'com.android.support:appcompat-v7:2x.x.x' under dependencies to the latest, then resynced, the red lines suddenly disappeared from MainActivity.java and everything became normal.
Maybe not the fiddling with sdk version numbers are important here, but to force a proper gradle resync.
Please note also, that since Gradle 3.4, under dependencies in build.gradle file some configuration words changed: compile, testCompile, androidTestCompile, testApi, androidTestApi become obsolete and should be replaced with implementation or api.
You can find more on this issue here: https://developer.android.com/studio/build/gradle-plugin-3-0-0-migration?utm_source=android-studio#new_configurations and a proper explanation on the difference between choosing implementation or api here: https://medium.com/mindorks/implementation-vs-api-in-gradle-3-0-494c817a6fa

Android Studio: Dependencies not included in Java module using Gradle 4.1

I have a Java module that generates some metadata for my Android app and needs to run as a regular Java application. After updating to Android Studio 3.0 (in 2.3.3 it worked as expected) I get a NoClassDefFoundError for the dependencies (in the case below for com/google/gson/GsonBuilder, the main method itself can be found).
I even tried putting the GSON Jar into the libs folder but it still throws the NoClassDefFoundError.
I assume the dependencies are not properly included. Any idea how to fix this?
The build.gradle looks like this:
apply plugin: 'java'
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.google.code.gson:gson:2.8.1'
}
sourceCompatibility = "1.7"
targetCompatibility = "1.7"
My class looks like this:
import com.google.gson.GsonBuilder;
public class myClass {
public static void main(String[] args) {
GsonBuilder builder = new GsonBuilder();
}
}
Use api instead of implementation.
From the docs
When your module configures an implementation dependency, it's
letting Gradle know that the module does not want to leak the
dependency to other modules at compile time. That is, the dependency
is available to other modules only at runtime.
Using this dependency
configuration instead of api or compile can result in significant
build time improvements because it reduces the amount of projects that
the build system needs to recompile. For example, if an implementation
dependency changes its API, Gradle recompiles only that dependency and
the modules that directly depend on it. Most app and test modules
should use this configuration.
See difference between api and implementation here for more info.
This is a problem probably related with Android Gradle plug-in. Try using compile instead of implementation in yourbuild.gradle`:
apply plugin: 'java'
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.google.code.gson:gson:2.8.1'
}
sourceCompatibility = "1.7"
targetCompatibility = "1.7"
The above is working in Android Studio 3.0 but with Android Gradle plug-in 2.3.3 in root build.gradle:
classpath 'com.android.tools.build:gradle:2.3.3'
UPDATE
I manage to make it works by adding google() to repositories block in root build.gradle. The following build.gradle is for the Java module:
apply plugin: 'java'
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.google.code.gson:gson:2.8.1'
}
sourceCompatibility = "1.8"
targetCompatibility = "1.8"
And this is my root build.gradle:
buildscript {
repositories {
jcenter()
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.0.0'
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3'
classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5'
}
}
allprojects {
repositories {
jcenter()
google()
}
}
Tested on Android Studio 3.0 with Gradle 4.1.

Android GoogleAPIClient - NoClassDefFoundError: com/google/android/gms/internal/zzsa

I'm developing an app that uses GoogleAPIClient to (obviously) get the user current location in background.
For this task I use IntentService with WakefulBroadcastReceiver (to get the location every hour). Everything was working fine on development environment but when deployed in Play Store some devices are getting this error:
Fatal Exception: java.lang.NoClassDefFoundError: com/google/android/gms/internal/zzsa
at com.google.android.gms.common.api.GoogleApiClient$Builder.<init>(Unknown Source)
at tellerina.com.br.vivara.services.MyService.onHandleIntent(MyService.java:37)
at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:157)
at android.os.HandlerThread.run(HandlerThread.java:61)
I have searched the internet for answers but I didn't find anything. Here's the point where the exception appears:
mGoogleApiClient = new GoogleApiClient.Builder(MyApplication.getContext())
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
Thanks a lot!
EDIT
app build.gradle
buildscript {
repositories {
maven { url 'https://maven.fabric.io/public' }
}
dependencies {
classpath 'io.fabric.tools:gradle:1.21.2'
}
}
apply plugin: 'com.android.application'
apply plugin: 'io.fabric'
android {
compileSdkVersion 23
buildToolsVersion "23.0.2"
defaultConfig {
applicationId "app.package"
minSdkVersion 14
targetSdkVersion 22
versionCode 9
versionName "1.5.2"
multiDexEnabled true
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
dexOptions {
javaMaxHeapSize "4g"
}
}
repositories {
mavenCentral()
maven { url 'https://maven.fabric.io/public' }
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile fileTree(dir: 'libs', include: ['*.so'])
compile(project(':volley')) {
exclude module: 'support-v4'
}
compile files('libs/commons-codec-1.9.jar')
compile('com.navercorp.volleyextensions:volley-views:2.0.+') {
exclude module: 'library'
}
compile('com.crashlytics.sdk.android:crashlytics:2.5.5#aar') {
transitive = true;
}
compile 'com.android.support:appcompat-v7:23+'
compile 'com.android.support:cardview-v7:23+'
compile 'com.android.support:recyclerview-v7:23+'
compile 'com.google.code.gson:gson:2.3.1'
compile 'io.card:android-sdk:5.1.1'
compile 'com.github.ksoichiro:androidpagecontrol:0.1.1'
compile 'me.relex:circleindicator:1.1.5#aar'
compile 'com.nineoldandroids:library:2.4.0'
compile 'com.daimajia.easing:library:1.0.1#aar'
compile 'com.daimajia.androidanimations:library:1.1.3#aar'
compile 'com.facebook.android:facebook-android-sdk:4.5.0'
compile 'br.com.jansenfelipe:androidmask:1.0.1'
compile 'com.google.android.gms:play-services:8.4.0'
compile 'com.android.support:multidex:1.0.0'
compile 'com.android.support:design:23+'
compile 'com.squareup.picasso:picasso:2.5.2'
}
apply plugin: 'com.google.gms.google-services'
Root project build.gradle
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.5.0'
classpath 'com.google.gms:google-services:+'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
}
}
EDIT 2
Using Fabric, now I can see that all of users affected by this problem is using Android 4.x. Maybe the distribution of Play Services is bugged, I don't know. But it's decreasing the number of devices with this error.
You are getting
Fatal Exception: java.lang.NoClassDefFoundError:
com/google/android/gms/internal/zzsa
at com.google.android.gms.common.api.GoogleApiClient$Builder.(Unknown
Source)
NoClassDefFoundError in Java comes when Java Virtual Machine is not able to find a particular class at runtime which was available during compile time.
OLD
dependencies {
// classpath 'com.android.tools.build:gradle:1.5.0'
// classpath 'com.google.gms:google-services:+' //(Avoid Calling "+")
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
GoogleApiClient is used with a variety of static methods. Some of
these methods require that GoogleApiClient be connected, some will
queue up calls before GoogleApiClient is connected;
mGoogleApiClient = new GoogleApiClient.Builder(this)
You should try with your build.gradle
Top-level build file where you can add configuration options common to
all sub-projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.0.0-beta2'
classpath 'com.google.gms:google-services:2.0.0-beta2'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
}
}
Advice
you can call
compile 'com.android.support:appcompat-v7:23.1.1' instead of
v7:23+
Then Clean-Rebuild-Restart-Sync Your Project .Hope this helps .
Edit
The Android build system consists of an Android plugin for Gradle.
Gradle is an advanced build toolkit that manages dependencies and
allows you to define custom build logic. Android Studio uses a Gradle
wrapper to fully integrate the Android plugin for Gradle. The Android
plugin for Gradle also runs independent of Android Studio.
A plugin is simply any class that implements the Plugin interface. Gradle provides the core plugins as part of its distribution so simply applying the plugin as above is all you need to do.
with beta2 and alpha-5 gradle dosen't show error. But without "apply
plugin: 'services'" and 'classpath' it's not generated
gcm_defaultSenderId for GCM
You can check Get an Instance ID
You should use apply plugin .
This is clearly a proguard configuration error of gms (Google Play Services).
Either it's caused by a wrong version that you build against, and you can build against another one.
Or it's caused by the Play Services installed on the device, and you can only hope that the Play Services team has stopped roolout of this version until the bug is fixed.
FINALLY! I spent literally several hours trying to resolve this issue, maybe it has already been resolved but it turns out any of the google classes you use have to all be the SAME VERSION in the gradle, i.e.
compile 'com.google.android.gms:play-services-identity:7.8.0'
compile 'com.google.android.gms:play-services-location:7.5.0'
I was calling two different versions. Once I chanced it to this:
compile 'com.google.android.gms:play-services-identity:7.8.0'
compile 'com.google.android.gms:play-services-location:7.8.0'
the classdeferror was resolved!

How to set source version of Java library in Android Studio project

I've got an Android project split into a pure Java library and the Android application. I'm using Gradle Retrolambda so I can write Java 8 code.
Android Studio 1.3 correctly recognises the android.compileOptions.sourceCompatibility in the Android module that I've set to JavaVersion.VERSION_1_8.
Now I'd like Android Studio to realise the Java module is also Java 8. I've tried (in the root of the Gradle script, after apply plugin 'java':
sourceCompatibility = 1.8 But doesn't work. Gradle correctly compiles, but Android Studio shows a warning ("Assignment not used") and assumes Java 6.
sourceCompatibility 1.8 doesn't compile.
How can I get Android Studio to recognise this without resorting to the "Set source version" quick fix? Or is it unimplemented for now?
EDIT
To clarify, the whole project does compile with ./gradlew assembleDebug. The problem is with Android Studio source highlighting.
My Java module build.gradle is as follows:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'me.tatarka:gradle-retrolambda:3.2.0'
}
}
repositories {
jcenter()
mavenCentral()
}
apply plugin: 'java'
apply plugin: 'me.tatarka.retrolambda'
sourceCompatibility = JavaVersion.VERSION_1_8
dependencies {
compile 'io.reactivex:rxjava:1.0.12'
compile 'io.reactivex:rxjava-string:1.0.0'
compile 'joda-time:joda-time:2.8.1'
testCompile 'junit:junit:4.12'
}
retrolambda {
jdk System.getenv("JAVA_HOME")
defaultMethods true
incremental false
}
And here's what Android Studio gives me:
in your java module build.gradle write code like this:
buildscript {
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
classpath "me.tatarka:gradle-retrolambda:3.2.0"
}
}
apply plugin: 'java'
apply plugin: 'me.tatarka.retrolambda'
repositories {
mavenCentral()
}
dependencies {
}
retrolambda {
jdk System.getenv("JAVA8_HOME")
defaultMethods true
incremental false
}
It would appear (thanks #Anand Singh) that Android Studio doesn't handle this yet, so you need to apply the quick fix.

Categories