Firebase-perf conflicting with let plugin - android

We were recently asked to implement "Firebase Performance Monitoring" on an Android app, but it's been causing us lots of different problems. The app used to work just fine, but upon adding "firebase-perf", it compiles, but then on runtime we found out the Let plugin stopped working, every permission defined with the #AskPermission annotation is simply ignored.
Looking through the gradle build output, I stumbled upon this stack-trace:
java.lang.IllegalStateException: Expecting .,<, or ;, but found firebaseperf while unpacking <K:Ljava/lang/Object;>Lcom/google/android/gms/internal/firebase-perf/zzw<TK;>;
at org.aspectj.util.GenericSignatureParser.parseClassTypeSignature(GenericSignatureParser.java:204)
at org.aspectj.util.GenericSignatureParser.parseAsClassSignature(GenericSignatureParser.java:56)
at org.aspectj.weaver.UnresolvedType.forGenericTypeSignature(UnresolvedType.java:274)
at org.aspectj.weaver.bcel.BcelWorld.addSourceObjectType(BcelWorld.java:482)
at org.aspectj.weaver.bcel.BcelWorld.addSourceObjectType(BcelWorld.java:456)
at org.aspectj.weaver.bcel.BcelWeaver.addAspectsFromJarFile(BcelWeaver.java:263)
at org.aspectj.weaver.bcel.BcelWeaver.addLibraryJarFile(BcelWeaver.java:236)
at org.aspectj.ajdt.internal.core.builder.AjBuildManager.initBcelWorld(AjBuildManager.java:874)
at org.aspectj.ajdt.internal.core.builder.AjBuildManager.performBuild(AjBuildManager.java:249)
at org.aspectj.ajdt.internal.core.builder.AjBuildManager.batchBuild(AjBuildManager.java:185)
at org.aspectj.ajdt.ajc.AjdtCommand.doCommand(AjdtCommand.java:112)
at org.aspectj.ajdt.ajc.AjdtCommand.runCommand(AjdtCommand.java:60)
at org.aspectj.tools.ajc.Main.run(Main.java:371)
at org.aspectj.tools.ajc.Main$run.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:133)
at com.canelmas.let.LetPlugin$_apply_closure2_closure3.doCall(LetPlugin.groovy:66)
...
I've seen some similar cases here and there but couldn't find a solution yet. The way I see it, it looks like a conflict between differing versions of aspectjs, defined in different classpaths.
This is the relevant part of out project-level gradle file:
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.0.1'
classpath group: 'org.tmatesoft.svnkit', name: 'svnkit', version: '1.7.11'
classpath('com.canelmas.let:let-plugin:0.1.11')
classpath 'com.google.gms:google-services:4.2.0'
classpath 'com.google.firebase:firebase-plugins:1.1.5'
}
}
And these are the firebase dependencies we have defined in the app-level gradle:
dependencies {
compile 'com.google.firebase:firebase-core:16.0.7'
compile 'com.google.firebase:firebase-perf:16.2.3'
}
Does anyone have an idea of a possible fix?
EDIT: There was someone in another thread, who claimed to have solved the problem with the code below, but I have no idea how to actually use it. Could anyone more Gradle-savvy be able to explain where is this declaration supposed to go and what I'm supposed to do with it?
I tried placing it many different places of my gradle file but I'm getting this error: "No such property: classpath for class: org.gradle.api.tasks.compile.JavaCompile"
def filtered_class_filetree = javaCompile.classpath.asFileTree.filter {
!it.canonicalPath.contains("firebase-perf")
}

If multiple libraries are compiling different versions of aspectj (or any other dependency), you can always force (or ignore) the ones you want like below:
implementation('com.google.firebase:firebase-core:16.0.7', { // this will remove aspectj dependencies from firebase
exclude group: 'org.aspectj', module: 'aspectjrt'
exclude group: 'com.android.support', module: 'aspectjtools'
})
You can also force aspect's version like below (beside your dependencies, in the module):
configurations.all {
resolutionStrategy.force 'org.aspectj:aspectjrt:x.x.x'
}
To answer your last question:
I tried placing it many different places of my gradle file but I'm
getting this error: "No such property: classpath for class:
org.gradle.api.tasks.compile.JavaCompile"
You can access java compiler (and classpath) using applicationVariants in android block inside your module:
// inside your android module
android {
//...
applicationVariants.all {
variant ->
variant.javaCompiler.classpath = variant.javaCompiler.classpath.filter {
!it.canonicalPath.contains("firebase-perf")
}
}
}

Related

Exclude a Gradle dependency that is added by the Realm plugin

Sporadically, my Gradle syncs will fail. I'll be given the unhelpful message that "a 3rd party Gradle plugin" may be the cause. If I open up the Event Log, I'll see the message:
Outdated Kotlin Runtime
Your version of Kotlin runtime in 'Gradle: org.jetbrains.kotlin:kotlin-stdlib:1.2.10#jar' library is 1.2.10-release-109 (1.2.10), while plugin version is 1.2.51-release-Studio3.1-1.
Runtime library should be updated to avoid compatibility problems.
The mismatched number is neither the Kotlin version in my Gradle files, or the version of my Kotlin plugin in Android Studio.
After running a Gradle dependency tree, I found the culprit:
+--- io.realm:realm-android-kotlin-extensions:5.1.0
| \--- org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.2.10 -> 1.2.51
I'm not including any realm-android-kotlin-extensions library. I'm assuming that it's added by classpath "io.realm:realm-gradle-plugin:5.1.0" and apply plugin: "realm-android"
This makes matters difficult. If it were a regular dependency, I could try something like
implementation "io.realm:realm-android-kotlin-extensions:5.1.0" {
transitive = false
}
or
implementation "io.realm:realm-android-kotlin-extensions:5.1.0" {
exclude group: "org.jetbrains.kotlin", module: "kotlin-stdlib-jdk7"
}
Theoretically that would probably work. It would be forced to use the newer version of Kotlin, the error would go away, and hopefully Gradle syncs would work and all would be well with the world. But if I try this approach my Gradle sync fails and I get this error in the Event Log:
Gradle sync failed: Could not find method io.realm:realm-android-kotlin-extensions:5.1.0() for arguments [build_2krw7i3nwfkd5lrq1ly9b8huw$_run_closure3$_closure29#7b5b2081] on object of type org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler.
I'm assuming that's because this isn't a dependency I added (perhaps not a public dependency?), that it fails because the dependency is added via the plugin instead of directly in my Gradle file.
So how do I fix this? Perhaps there's a line I can add to tell the Realm plugin to exclude the obsolete dependency? Or am I completely barking up the wrong tree and the solution for my Kotlin version clash issue is something else entirely?
(BTW, if you're wondering why I'm using Realm 5.1.0, 5.3.1 causes some weird bugs in our app, so we're waiting for a later version to be released in the hope that will no longer cause the issues.)
One of the things on my personal "I wish I had known this a year ago" list is that you can manually add what Realm adds to your project instead of relying on the Gradle plugin.
buildscript {
ext.kotlin_version = '1.2.51'
ext.realm_version = '5.3.1'
repositories {
jcenter()
mavenCentral()
}
dependencies {
classpath "io.realm:realm-transformer:5.1.0"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
import io.realm.transformer.RealmTransformer
android.registerTransform(new RealmTransformer(project))
dependencies {
implementation "io.realm:realm-annotations:$realm_version"
implementation "io.realm:realm-android-library:$realm_version"
implementation "io.realm:realm-android-kotlin-extensions:$realm_version" {
exclude group: "org.jetbrains.kotlin", module: "kotlin-stdlib-jdk7"
}
kapt "io.realm:realm-annotations-processor:$realm_version"
}
As per docs.

Firebase Performance Beta / Plugin build issue

When integrating the current Android Firebase Performance Monitoring (beta) version released during I/O 2017 as follows...
Add to project build.gradle:
dependencies {
classpath 'com.google.firebase:firebase-plugins:1.1.0'
}
Add to app build.gradle:
dependencies {
compile 'com.google.firebase:firebase-perf:10.2.6'
}
You may come across the following build error.
Error:Execution failed for task ':app:packageDebug'.
> com.google.common.util.concurrent.MoreExecutors.directExecutor()Ljava/util/concurrent/Executor;
This is caused by a Guava dependency mismatch, which can be resolved as follows, by modifying the project build.gradle as follows:
dependencies {
classpath ('com.google.firebase:firebase-plugins:1.1.0') {
exclude group: 'com.google.guava', module: 'guava-jdk5'
}
}
The Firebase team are aware of this issue, suggested the above workaround and will be fixing in a future release.
Putting this out there to help anyone else scratching their head.
This issue was fixed in version 1.1.1 of firebase plugins. To use the updated version just update your project-level build.gradle file as follows:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath ('com.google.firebase:firebase-plugins:1.1.1')
}
}

How to use realm 2.2.0-Snapshot

I try to evaluate the performance of the Realm database for a specific project.
Everything works fine at the moment. I just miss one method. I need a function to get the needed space for storing my realm database.
In case of some other databases I can take the size of the files where it is stored in. How can I get the needed space for my specific realm database?
And more important for me is the version. Evertything I tried works just fine with version 0.88.0
I just need to add the following dependency to my modules gradle file.
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
provided 'io.realm:realm-android:0.80.0'
...
}
If I change this to
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
provided 'io.realm:realm-android:2.2.0'
...
}
I got the following error:
Error:(24, 13) Failed to resolve: io.realm:realm-android:2.2.0-snapshot
How can I change to the newest version?
Because of debugging I got version 2.1.0 working for me. Hope that I can copy the classes of the TestProject to my bigger Evaluation Project without getting errors. If not I will report that.
But first, I need some code to get the needed diskspace for storing the whole database. I need this to compare it to other Databases.
To use Realm's SNAPSHOT version, you need to add their snapshot repository in your build gradle.
buildscript {
repositories {
jcenter()
maven {
url 'http://oss.jfrog.org/artifactory/oss-snapshot-local'
}
}
dependencies {
classpath "io.realm:realm-gradle-plugin:<version>-SNAPSHOT"
}
}
repositories {
jcenter()
maven {
url 'http://oss.jfrog.org/artifactory/oss-snapshot-local'
}
}
To use Realm in your project, you need to apply it as a Gradle plugin (since 0.88.0).
apply plugin: 'realm-android'
For more info, refer to the official documentation: https://realm.io/docs/java/latest/#installation
Remove the -SNAPSHOT part from the version and its actually 2.1.1 is the latest version as for now, so the main part should be
buildscript {
repositories {
jcenter()
}
dependencies {
classpath "io.realm:realm-gradle-plugin:2.1.1"
}
}
They really have some issue with the realm-annotations-processor of version 2.2.0-SNAPSHOT (its missing, check here). The latest version they did provide is 2.0.2-SNAPSHOT and thus if you want to use the SNAPSHOT then you should use 2.0.2-SNAPSHOT version.

Gradle syncing keeps failing

I'm trying to include Android Asynchronous Http Client and Picasso into my Android project using Gradle. Here's my build.gradle file.
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.9.+'
}
}
allprojects {
repositories {
mavenCentral()
}
dependencies {
compile 'com.loopj.android:android-async-http:1.4.4'
compile 'com.squareup.picasso:picasso:2.1.1'
}
}
When I try to sync it, I keep getting the following error.
No signature of method: org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler.compile() is applicable for argument types: (java.lang.String) values: [com.loopj.android:android-async-http:1.4.4]
Possible solutions: module(java.lang.Object)
I'm very new to Android so I'm clueless on how to correct this. Can anyone please help me out? I'm using Android Studio version 0.5.8 by the way.
Thank you.
Don't include dependencies in your top-level build file. Include them in module-level build files instead. If you use the Project Structure UI instead of modifying build files directly, it will set things up properly.

In Android Gradle, is there any way to use local snapshot dependencies?

My Android app is based on Gradle and it just takes ages to build every time. This is due to the number of modules I have. Even if there are no changes in submodules, it keeps rebuilding every sources.
I was wondering if there is any way to convert these modules to local snapshot dependencies as I'm not updating them often?
I'm pretty sure it's possible but I have a very basic experience with gradle and maven so I can't figure out a simple way to do that.
Basically right now I'm listing my dependencies like that:
dependencies {
compile project(':Library:lib1')
compile project(':Library:lib2')
compile project(':Library:lib3')
}
and I'd like to use something like that:
repositories {
local()
}
dependencies {
compile 'com.lib1:lib:SNAPSHOT-1.0')
compile 'com.lib2:lib:SNAPSHOT-1.0')
compile 'com.lib3:lib:SNAPSHOT-1.0')
}
To use local snapshots use the maven-publish plugin. If you use SNAPSHOT in the version (e.g. 0.0.1-SNAPSHOT) you will publish snapshots to your local repository. For the build.gradle for lib1 you should do something like this:
apply plugin: 'java'
apply plugin: 'maven-publish'
project.version=0.0.1-SNAPSHOT
publishing {
publications {
maven(MavenPublication) {
from components.java
}
}
}
and run the :publishMavenPublicationToMavenLocal target.
In you gradle build file for projects using the library use:
repositories {
local()
}
dependencies {
compile group: 'com.lib1', name: 'lib', version: 'SNAPSHOT-0.0.1', changing: true
}
The 'changing' attribute indicates that not a cached version is used (normally updated once every 24hrs) but always checks for the latest.

Categories

Resources