Why am I getting a ClassNotFoundException from Play Services lib when using Proguard? - google-play-services

I just turned on ProGuard on my build and now I'm getting a
java.lang.ClassNotFoundException: Didn't find class "com.google.android.gms.chimera.GmsModuleInitializer" on path: DexPathList[[zip file "/system/app/PlayGames.apk"],nativeLibraryDirectories=[/vendor/lib, /system/lib]]
The docs say that everything that I need to use Proguard with Play Services should be included by the Android Gradle plugin:
Note: ProGuard directives are included in the Play services client
libraries to preserve the required classes. The Android Plugin for
Gradle automatically appends ProGuard configuration files in an AAR
(Android ARchive) package and appends that package to your ProGuard
configuration. During project creation, Android Studio automatically
creates the ProGuard configuration files and build.gradle properties
for ProGuard use. To use ProGuard with Android Studio, you must enable
the ProGuard setting in your build.gradle buildTypes. For more
information, see the ProGuard guide.
This the important part of my app module build.gradle file:
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "23.0.3"
defaultConfig {
...
}
...
buildTypes {
...{
applicationIdSuffix ".debug"
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'),
'proguard-rules.pro'
}
}
}
dependencies {
...
//google play services
compile 'com.google.android.gms:play-services-gcm:8.4.0'
compile 'com.google.android.gms:play-services-analytics:8.4.0'
compile 'com.google.android.gms:play-services-location:8.4.0'
}
This is my top level build.gradle file:
buildscript {
repositories {
jcenter()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.1.2'
}
}
allprojects {
repositories {
jcenter()
mavenCentral()
}
}
What am I missing?

ClassNotFoundException usually occurs when an application tries to load in a class through its string name but no definition for the class with the specified name could be found.
From this forum, you can fix it by adding com.google.android.gms.** { *; }.
Just add to your proguard-project.txt:
keep class com.google.android.gms.** { *; }
dontwarn com.google.android.gms.**
You can also check on the suggested comment in this SO question.
Google Play Services aars contain proguard.txt with the necessary clauses. So the setting shouldn't really be necessary. You can investigate what happened with the fragment in ProGuard output files. Check app/build/output/mapping/{buildVariant}/usage.txt and mapping.txt. The fragment should be mentioned in one of those.
Hope this helps!

I know this is a rather old post but I would like to highlight the following should it help someone in the future.
Like #abielita mentioned, the ClassNotFoundException is caused by an unhandled case of reflection.
When using broad -keep options (ending with .** { *; }), you will instruct ProGuard not to shrink, optimize or obfuscate all classes and classmembers for the package name mentioned before the wildcards. This will eventually lead in a poorly optimized project. Therefore, it's better to narrow down such -keep option to only target the missing class. In OP's example, adding a -keep option for the missing class like shown below will tackle this particular issue;
-keep class com.google.android.gms.chimera.GmsModuleInitializer
ProGuard can help you set up narrowed down -keep options if you add -addconfigurationdebugging to the configuration file, more details on this feature is documented in the ProGuard manual, here.
Recently the ProGuard Playground was released, you can quickly visualise the effect of the broad -keep options vs the narrowed down ones. A nice benefit here is that you do not need to continuously (re-)build the project.

Related

Serialize kotlin data class in gradle's buildSrc/ during build

I'm looking to produce json files during the build cycle of my kotlin gradle app. My intent is to be able to instantiate data classes with a combination of public and private app configuration values that get put into the build's resources directory.
I'm looking at kotlinx.serialization, and I'd like to define these classes ideally in the projet's buildSrc/.
I haven't found any resources online for trying to setup serialization within gradle's build process, and not just configuring it for the app at runtime. This is what I've put together as my buildSrc/build.gradle.kts
plugins {
`kotlin-dsl`
kotlin("plugin.serialization") version "1.3.72"
}
repositories {
jcenter()
}
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.1.0")
}
And this is my test data class:
#Serializable
data class JsonGenerator(val x: String = "")
The error I get is:
Cannot access 'Serializable': it is internal in 'kotlin.io'
It seems that this error can happen when the dependency isn't properly declared. But I'm still unclear whether buildSrc has restrictions that make this impossible or not. I'm not married to this approach, but this seemed like the best solution.
Edit:
I've changed my buildSrc/build.gradle.kts to:
plugins {
`kotlin-dsl`
}
repositories {
jcenter()
}
dependencies {
implementation(kotlin("serialization"))
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.0.1")
}
Structure:
buildSrc
main
Kotlin
MyTempClass.kt
It is important for the kt file to not be nested, I think that will only work if the file is the same name as the nesting directory
Inside of my data class file:
import kotlinx.serialization.*
#Serializable
data class MyTempClass(val name: String)
I had a specific implementation of serialization, without the plugin.
Then in the top level build.gradle.kts, the MyTempClass was accessible

Using gradle convention plugin to set kotlin jvmTarget option

Using a Gradle convention plugin to share common configuration between subprojects, what is the correct way to set Kotlin compiler options, like jvmTarget?
This plugin setup results in a working build, but IntelliJ doesn't understand it, which leads me to think this isn't the correct approach:
plugins {
id 'org.jetbrains.kotlin.jvm'
}
repositories {
jcenter()
}
dependencies {
// shared dependencies
}
tasks.named('test') {
useJUnitPlatform()
}
tasks {
compileKotlin {
kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
kotlinOptions.jvmTarget = "1.8"
}
}
This plugin is applied in subprojects like this:
plugins {
id 'my.kotlin-conventions'
id 'java-library'
}
I'm using Gradle 6.7, Kotlin 1.4.20.
Edit: More info regarding IntelliJ problem
In IntelliJ, in sub-projects, I am seeing the warning Cannot inline bytecode built with JVM target 1.8 into bytecode that is being built with JVM target 1.6. Please specify proper '-jvm-target' option. In the root project I don't see the warning, only in sub-projects. Building and running the project produces no problems (or warnings) at all.
Sample: https://github.com/nieldw/IntelliJ_Gradle_Convention_Plugin_Issue
IntelliJ seems to not like the buildSrc/settings.gradle file. When I remove it and “Reload All Gradle Projects”, then the errors that you’ve described disappear.
Commenting the rootProject.name=… line in the buildSrc/settings.gradle file works, too. Interestingly, uncommenting the line later (and reloading the Gradle configuration) is possible without breaking the IntelliJ configuration. So this should be your fix, I suppose.
Your build configuration looks correct to me. This rather sounds like a bug in IntelliJ’s Gradle support.

How to build kotlinx.coroutines in Kotlin/Native (test version 0.23.4-native-1)

This question is a continuation of this thread:
https://github.com/Kotlin/kotlinx.coroutines/issues/246#issuecomment-407023156
I am trying to use org.jetbrains.kotlinx:kotlinx-coroutines-core-native:0.23.4-native-1 in a Kotlin/Native project targeting iOS.
build.gradle:
buildscript {
repositories {
mavenCentral()
maven { url "https://dl.bintray.com/jetbrains/kotlin-native-dependencies" }
}
dependencies {
classpath 'org.jetbrains.kotlin:kotlin-native-gradle-plugin:0.8'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.2.51"
}
}
apply plugin: 'kotlin-platform-native'
repositories {
jcenter()
mavenCentral()
maven { url "https://kotlin.bintray.com/kotlinx" }
}
sourceSets {
main {
component {
target 'ios_arm32', 'ios_arm64', 'ios_x64'
outputKinds = [KLIBRARY]
}
}
}
dependencies {
expectedBy project(':common')
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core-native:0.23.4-native-1"
}
The kotlinx:kotlinx-coroutines-core-native dependency doesn't seem to work, as the produces build errors like:
error: unresolved reference: coroutines
import kotlinx.coroutines.experimental.*
^
If I manually include the artifact dependencies such as org.jetbrains.kotlinx:kotlinx-coroutines-core-native_release_ios_x64:0.10.3-native, then I get a complier exception:
exception: java.lang.IllegalStateException: Could not find "atomicfu-native"
This error persists, even if I also add org.jetbrains.kotlinx:atomicfu-native:0.10.3-native dependency.
Here is a list of things to check for (I have been through this, and finally made it work) :
Enable Gradle metadata. It's required to retrieve the coroutines dependencies. To do so, add this line in your "settings.gradle" file, after all the "include" instructions :
enableFeaturePreview('GRADLE_METADATA')
use gradle 4.7 (newer version are incompatible with the meta data of the current coroutines library, they require something with 0.4 version and the current published one uses 0.3)
In the iOS module :
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core-native:0.23.4-native-1"
In your common module :
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:0.23.4"
If you have a js module, it may fail due to the gradle metadata feature. You can fix it by adding this before each of your "repositories" blocks (https://github.com/srs/gradle-node-plugin/issues/301)
repositories.whenObjectAdded {
if (it instanceof IvyArtifactRepository) {
metadataSources {
artifact()
}
}
}
Hope this will be enough !

Could not resolve com.android.support:design:26.1.0

I have been having this problem for quite a while, that my com.android.support:design:26.1.0 fails me and I have no clue what to change anymore.
These are my files for module gradle.
Build.gradle (app)
apply plugin: 'com.android.application'
android {
compileSdkVersion 26
buildToolsVersion '26.0.2'
defaultConfig {
applicationId "com.xxx.yyy"
minSdkVersion 16
targetSdkVersion 26
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'])
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
implementation 'com.android.support:design:26.1.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
compile 'com.android.support:support-v4:26.1.0'
compile 'com.google.android.gms:play-services-vision:9.4.0'
// compile 'com.android.support:design:26.1.0'
}
//apply plugin: 'com.google.gms.google-services'
The project gradle file
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
google()
jcenter({ url "http://jcenter.bintray.com/" })
}
dependencies {
classpath 'com.android.tools.build:gradle:3.0.1'
// classpath 'com.google.gms:google-services:3.2.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
jcenter({ url "http://jcenter.bintray.com/" })
maven { url "https://maven.google.com" }
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
Error:Unable to resolve dependency for
':app#releaseUnitTest/compileClasspath': Could not resolve
com.android.support:design:26.1.0.
Error:Unable to resolve dependency
for ':app#release/compileClasspath': Could not resolve
com.android.support:design:26.1.0.
Error:Unable to resolve dependency
for ':app#debugUnitTest/compileClasspath': Could not resolve
com.android.support:design:26.1.0.
Error:Unable to resolve dependency
for ':app#debugAndroidTest/compileClasspath': Could not resolve
com.android.support:design:26.1.0.
Error:Unable to resolve dependency
for ':app#debug/compileClasspath': Could not resolve
com.android.support:design:26.1.0.
And only the 'Snackbar' function does not work but rest of it seems fine.
When I change the design to 25.1.0 version instead, it works but it clashes with other 26.1.0 ones so it's not recommended by the Android Studio. Anyone..?
I have tried putting the
compile 'com.android.support:design:26.1.0'
instead of implement, it does not work. When I tried to change the whole thing to either 25.4.0 or any other 25 version, a lot of other things doesnt compile as well. I have unchecked the Offline work, tried removing / adding maven directory, un-commenting a few more of dependencies, changing all to compile instead of implement but just gives me more errors.
Yes I have updated all my SDKs to the newest but I have a feeling that Gradle just cannot download certain dependencies from the websites that's why I cannot download any more of the other dependencies. (Although my off-line work is unchecked)
Also, whatever that are uncommented in the code above, it means I have tried inputting those lines but it did not solve the issue or rather created more issues.
Here is the way i found it please try the below
Go to File->Settings->Build, Execution, Deployment->Gradle->Uncheck Offline work option.
Try this once ,instead of implementing compile the design support gradle code
compile 'com.android.support:design:26.1.0'
and remove this
implementation 'com.android.support:design:26.1.0'
Problem that I realized in the end was that when I was setting up the android proxy, I have only set up 1 proxy which was for HTTP and did not realize that HTTPS proxy was not set up.
So after fixing that issue by setting HTTPS proxy, there was no more problems.

Kotlin Foo::class.java "Unresolved Reference: Java" error

I am trying to convert my Java code of HomePage.class to Kotlin. I am following the instructions on Kotlin.org:
getClass()
To retrieve the type information from an object, we use the javaClass
extension property.
val fooClass = foo.javaClass
Instead of Java’s Foo.class use
Foo::class.java.
val fooClass = Foo::class.java
I have a class called HomePage that extends AppCompatActivity (in Android). I am using Android Studio. I tried doing HomePage::class.java and it has an error: Unresolved reference: java
How do I get this to work?
The issue is most likely that you forgot to depend on the reflection libraries which were needed for the reflective functions of Kotlin.
On the Java platform, the runtime component required for using the
reflection features is distributed as a separate JAR file
(kotlin-reflect.jar). This is done to reduce the required size of the
runtime library for applications that do not use reflection features.
If you do use reflection, please make sure that the .jar file is added
to the classpath of your project.
Source
It turns out, I was using an older version of Kotlin, and it wasn't configured correctly. I edited the gradle file to include the latest beta version, and selected the option that configures Kotlin, and it works now.
In gradle:
buildscript {
ext.kotlin_version = '1.0.0-beta-3594'
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "org.jetbrains.kotlin:kotlin-android-extensions:$kotlin_version"
}
}
...
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
}
I Put in the beginning of Gradle (Module app)
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
and
implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
or
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
in the dependencies section
In the build.gradle (Project)
buildscript {
ext.kotlin_version = '1.2.0'
repositories {
jcenter()
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.0.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
For easy reference, here are the reflection dependencies when using Gradle:
Reflection libraries from the docs for Gradle in your build.gradle
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
compile "org.jetbrains.kotlin:kotlin-reflect"
testCompile "org.jetbrains.kotlin:kotlin-test"
testCompile "org.jetbrains.kotlin:kotlin-test-junit"
}
Reflection libraries syntax for Kotlin Script Gradle DSL in your build.gradle.kts
dependencies {
compile(kotlin("stdlib"))
compile(kotlin("reflect"))
compile(kotlin("test"))
compile(kotlin("test-junit"))
}
In build.gradle (app) I had:
implementation 'androidx.core:core-ktx:1.6.0'
And I replaced it by
implementation 'androidx.core:core-ktx:1.5.0'
And it worked!
The core version also killed some of y functions like: forEach
I used
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
Instead of
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
i use this
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
invalided cache & restart android studio!works fine!!
This happened to me after updating Android Studio and the Kotlin plugin, which required migration to a newer version of Kotlin. After configuring everything correctly, the error still persisted. Deleting .idea folder and reloading did not help, but good old File -> Invalidate Caches / Restart did the trick for me.
I copied the class from other project and forgot to change the class package name.
when I changed, it fixed
I saw this in AndroidStudio with Kotlin 1.2.71 and none of the above fixed it for me.
What sadly hilariously worked for me was closing the project, telling AndroidStudio to forget about the project and re-opening from the folder. Presto, no unresolved reference. Weird, I know.
In my case reducing version of kotlin fixed the issue
Change
ext.kotlin_version = '1.3.21'
To
ext.kotlin_version = '1.3.11'
Add this line in your Module build gradle
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
In Project build gradle:
buildscript {
ext.kotlin_version = '1.3.21'
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.3.2'
classpath 'com.google.gms:google-services:4.2.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
I encountered this error when i downloaded and run android studio canary(artic fox). Since then my android studio(normal one) was giving this error i applied all the solutions given above but nothing worked . So i completely uninstalled the android studio and reinstalled the latest one (this was the only option left)