I have been charged with integrating Dagger in our existing project and I am having a bit of a problem with the dagger annotation processor.
My environment is pretty restricted so I cannot just use jcenter() or even Google Maven to get dependencies. We have an internal Ivy repo that stores and manages all of our Dependencies.
That said, I have pulled down all the dependencies that Dagger requires but I still have an issue. Gradle sync finishes successfully and resolves the dependencies, however when I go to build I get the following error.
error: Bad service configuration file, or exception thrown while
constructing Processor object: javax.annotation.processing.Processor:
Provider dagger.internal.codegen.ComponentProcessor could not be
instantiated: java.lang.NoClassDefFoundError:
com/google/common/collect/SetMultimap
Clearly I am missing a dependency as when I specifically specify and allow jcenter() and Google Maven as repositories, which I can do for testing purposes, but for prod building this cannot be allowed, I am able to build with no exceptions.
Now a strict reading of the error tells me that Dagger cannot find com.google.comm.collect.SetMutliMap.
I have searched quite a bit trying to find this dependency and about all I can find is that this file is a part of Guava or at least some of its functions are.
One thing to note is I am using the following version of gradle:
classpath 'com.android.tools.build:gradle:3.0.0'
Here is my dagger dependency in build.gradle which is an older version:
//Dagger
compile 'com.google.dagger:dagger:2.10'
annotationProcessor 'com.google.dagger:dagger-compiler:2.10'
Other dependencies:
//lifecycle libs
compile "android.arch.lifecycle:runtime:1.0.3"
compile "android.arch.lifecycle:extensions:1.0.0"
annotationProcessor "android.arch.lifecycle:compiler:1.0.0"
compile 'de.greenrobot:eventbus:2.4.1'
compile 'org.apache.commons:commons-lang3:3.4'
compile 'commons-io:commons-io:2.4'
compile 'com.android.support:multidex:1.0.1'
compile 'com.android.support:support-v4:26.1.0'
compile 'com.android.support:design:26.1.0'
compile 'com.github.ganfra:material-spinner:2.0.0'
compile 'com.nulab-inc:zxcvbn:1.1.3'
compile('com.google.android.gms:play-services-vision:10.2.1') {
exclude group: 'com.android.support'
}
compile 'org.zakariya.stickyheaders:stickyheaders:0.7.6'
compile 'com.google.code.gson:gson:2.8.0'
compile('com.google.android.gms:play-services-gcm:10.2.1') {
exclude group: 'com.android.support'
}
compile('com.google.android.gms:play-services-maps:10.2.1') {
exclude group: 'com.android.support'
}
compile('com.google.android.gms:play-services-location:10.2.1') {
exclude group: 'com.android.support'
}
compile 'com.android.support:appcompat-v7:26.1.0'
compile 'com.android.support:cardview-v7:26.1.0'
compile 'com.android.support:support-annotations:26.1.0'
//retrofit dependencies
compile 'com.squareup.okhttp3:okhttp:3.9.0'
compile 'com.squareup.retrofit2:retrofit:2.3.0'
compile 'com.squareup.retrofit2:converter-gson:2.3.0'
compile 'com.squareup.okhttp3:logging-interceptor:3.9.0'
Due to my restricted environment, I cannot update dependencies as I would like to do, so working within what I have, does anyone have any ideas on how to resolve this?
Thanks
As it turns out com.google.common.collect is part of com.google.guava
With that find in hand I found a solution that works. For whatever reason dagger-compiler was not resolving its own dependency, which is com.google.guava.
My solution consists of excluding the guava dependency from the compiler and adding it to the annotationProcessor path. I also exclude find bugs for my case as an older version is a dependency in our test project.
annotationProcessor ('com.google.guava:guava:22.0'){
exclude group: 'com.google.code.findbugs'
}
annotationProcessor('com.google.dagger:dagger-compiler:2.13') {
exclude group: 'com.google.guava'
}
Related
I don't know how to best deal with including dependencies in an Android library and cannot find any clear explanation elsewhere.
I have created an Android library that includes these dependencies:
compile 'com.android.support.constraint:constraint-layout:1.0.2'
compile 'com.android.support:appcompat-v7:25.3.1'
compile 'com.android.support:design:25.3.1'
compile 'com.android.support:support-v4:25.3.1'
compile 'com.android.support:recyclerview-v7:25.3.1'
compile 'com.squareup.okhttp3:okhttp:3.9.0'
compile 'com.github.bumptech.glide:glide:4.1.1'
annotationProcessor 'com.github.bumptech.glide:compiler:4.1.1'
Is it "good practice" to include the dependencies like this? what happens when my library is included in an app, and the app itself includes the same dependencies? how are these "duplicate" dependencies handled?
What is the best way to include dependencies in an Android library if the possibility exists that an app using the library may also include the same dependencies?
The best practice is to avoid duplicates (because it can make problem with your build), you can add exclude clauses in each project build.gradle file.
For example:
compile('com.github.bumptech.glide:glide:4.1.1') {
exclude group: 'com.android.support', module: 'support-v4'
}
The default behaviour is to settle on the newest version of the requested dependency - the newest means the highest version number.
If you want to check if there are duplicates you can visualize library dependencies in tree with the command:
gradlew -q dependencies yourProject:dependencies --configuration compile
You can find more information here
I have been developing and working on my App, I then decided to build the APK I then got duplicate file error specifically talking about firebase zzc.class? which I could not find. I have seen duplicate file error before and sorted it out but this Firebase error has really slowed down my work because I have seen no specific answer to my issue.
Below are my dependencies
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
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:25.+'
compile 'com.android.support:support-v4:25.+'
compile 'com.android.support:design:25.+'
compile 'com.google.firebase:firebase-auth:10.0.1'
compile 'com.google.firebase:firebase-database:10.0.1'
compile 'com.firebase:firebase-client-android:2.3.1'
compile 'com.google.firebase:firebase-storage:10.0.1'
compile 'com.firebaseui:firebase-ui:2.0.1'
compile 'org.apache.pdfbox:pdfbox:2.0.0'
compile 'net.igenius:customcheckbox:1.3'
compile 'com.roger.catloadinglibrary:catloadinglibrary:1.0.1'
testCompile 'junit:junit:4.12'
}
Then the error:
You are using different versions of the same libraries:
compile 'com.google.firebase:firebase-auth:10.0.1'
compile 'com.google.firebase:firebase-database:10.0.1'
compile 'com.google.firebase:firebase-storage:10.0.1'
compile 'com.firebaseui:firebase-ui:2.0.1'
As you can read here there is a dependency between firebaseui and firebase libraries:
FirebaseUI Version Firebase/Play Services Version
2.3.0 11.0.4
2.2.0 11.0.4
2.1.1 11.0.2
2.0.1 11.0.1
Use the same version to avoid these issue.
Also there is no reason to use the old:
compile 'com.firebase:firebase-client-android:x.x.x'
Check the migration guide and use:
compile "com.google.firebase:firebase-database:X.X.X"
Keep in mind that the latest version requires the google maven repo:
allprojects {
// ...
dependencies {
// ...
maven {
url "https://maven.google.com" // Google's Maven repository
}
}
}
This is happening because you have a duplicate in your build.gradle file. To solve this, you need to remove the following line of code:
compile 'com.firebase:firebase-client-android:2.3.1'
You cannot mix the old version of dependency with the new one.
Make sure to update firebase version to latest available version in your build(app) configuration exactly mentioned in the firebase documentation.
[https://firebase.google.com/docs/android/setup/]
If you are using play services make sure that the version of firebase library should be exactly same as of play services version.
compile 'com.google.android.gms:play-services:11.2.0'
compile 'com.google.firebase:firebase-core:11.2.0'
compile 'com.google.firebase:firebase-messaging:11.2.0'
If there is a library conflict then add gradle as:
defaultConfig {
multiDexEnabled true
}
and in your baseapplication
#Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}
This entry in my gradle file :
androidTestCompile ('com.squareup.okhttp:mockwebserver:2.7.0')
is throwing error:
Warning:Conflict with dependency 'com.squareup.okio:okio'. Resolved versions for app (1.8.0) and test app (1.6.0) differ. See http://g.co/androidstudio/app-test-app-conflict for details.
I tried commenting out different compile entries in my gradle file to find out which one was conflicting but I just can't find which one uses com.squareup.okio:okio.
UPDATE:
I was able to get the dependencies by running: gradlew.bat app:dependencies > c:\tmp\output.txt
+--- com.squareup.retrofit2:retrofit:2.0.0 -> 2.1.0
| \--- com.squareup.okhttp3:okhttp:3.3.0
| \--- com.squareup.okio:okio:1.8.0
--- com.squareup.okhttp:mockwebserver:2.7.0
| +--- com.squareup.okhttp:okhttp:2.7.0
| | \--- com.squareup.okio:okio:1.6.0
So as you can see, retrofit 2.0 uses okhttp3 which uses okio:1.8.0. On the other hand mockwebserver:2.7.0 uses okhttp:2.7.0 which uses okio:1.6.0. So how can I resolve this?
Here are the entries in "dependencies" section of my gradle file:
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:24.2.1'
//retrofit
compile 'com.squareup.retrofit2:retrofit:2.0.0'
compile 'com.squareup.retrofit2:converter-gson:2.+'
compile 'com.squareup.retrofit2:adapter-rxjava:2.+'
compile 'com.squareup.retrofit2:retrofit-mock:2.+'
//recycler view
compile 'com.android.support:recyclerview-v7:+'
//picasso image caching
compile 'com.squareup.picasso:picasso:2.5.2'
//jackson parser
compile (
[group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.4.1']
)
//Dagger
compile 'com.google.dagger:dagger:2.7'
apt 'com.google.dagger:dagger-compiler:2.7'
//constraint based layouts
compile 'com.android.support:design:24.1.1'
compile 'com.android.support.constraint:constraint-layout:1.0.0-beta4'
//for chrome debugging
compile 'com.facebook.stetho:stetho:1.4.1'
compile 'com.facebook.stetho:stetho-okhttp3:1.4.1' //for retrofit
//RxJava
compile 'io.reactivex:rxandroid:1.2.1'
// Because RxAndroid releases are few and far between, it is recommended you also
// explicitly depend on RxJava's latest version for bug fixes and new features.
compile 'io.reactivex:rxjava:1.1.6'
//--- For Testing ---
//robolectric:
testCompile "org.robolectric:robolectric:3.2.2"
//mockito
testCompile "org.mockito:mockito-core:2.+"
testCompile('org.hamcrest:hamcrest-core:1.3')
testCompile('org.hamcrest:hamcrest-library:1.3')
testCompile 'junit:junit:4.12'
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
// Espresso-web for WebView support
androidTestCompile( 'com.android.support.test.espresso:espresso-web:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
androidTestCompile( 'com.android.support.test:runner:0.5', {
exclude group: 'com.android.support', module: 'support-annotations'
})
androidTestCompile( 'com.android.support.test:rules:0.5', {
exclude group: 'com.android.support', module: 'support-annotations'
})
testCompile ('org.powermock:powermock-api-mockito:1.6.2') {
exclude module: 'hamcrest-core'
exclude module: 'objenesis'
}
//mockwebserver
//testCompile 'com.squareup.okhttp3:mockwebserver:3.3.0'
androidTestCompile ('com.squareup.okhttp:mockwebserver:2.7.0')
androidTestCompile 'com.squareup.spoon:spoon-client:1.2.0'
I solved by using
Retrofit version 2.3.0 -> com.squareup.retrofit2:retrofit:2.3.0
MockWebServer version 3.8.0 -> com.squareup.okhttp3:mockwebserver:3.8.0
try exclude okio from androidTestCompile
androidTestCompile ('com.squareup.okhttp:mockwebserver:2.7.0') {
exclude module: 'com.squareup.okio'
}
When instrumentation tests are run, both the main APK and test APK share the same classpath. Gradle build will fail if the main APK and the test APK use the same library (e.g. Guava) but in different versions. If gradle didn't catch that, your app could behave differently during tests and during normal run (including crashing in one of the cases).
ref - https://sites.google.com/a/android.com/tools/tech-docs/new-build-system/user-guide#TOC-Resolving-conflicts-between-main-and-test-APK
Which means dependencies in each configuration i.e compile, androidTestCompile & testCompile should be of the same versions.
Resolving the conflict
Update parent dependencies(retrofit & mockwebserver) such that they all share the same child dependencies(okhttp & okio) across configurations.
OR
Explicitly add the dependency in the configuration(compile, androidTestCompile or testCompile) that has the least version.
In your case adding androidTestCompile('com.squareup.okio:okio:1.6.0') should resolve the conflict.
Now each androidTest dependency that needs okio will use the latest version.
Note
Whenever there are version conflicts within the same configuration, the latest available version of the dependency is automatically used. This is not the case for version conflicts across configurations, hence the error.
example - Here in my compile configuration okhttp3 dependencies are replaced with the latest version of 3.9.0 whenever there is a conflict.
The dependency versions for these two versions of Retrofit and MockWebServer line up:
com.squareup.retrofit2:retrofit:2.2.0
com.squareup.okhttp3:mockwebserver:3.6.0
Rather than deal with dependency conflicts, I'd recommend using these two versions.
my app uses these dependencies
compile 'com.android.support:appcompat-v7:22.2.1'
compile 'com.android.support:design:22.2.1'
compile 'com.google.android.gms:play-services:7.0.0'
compile 'com.google.code.gson:gson:2.2.4'
when i imported seek arc library it uses different dependencies
compile 'com.android.support:appcompat-v7:23.4.0'
compile 'com.android.support:appcompat-v7:23.2.1'
compile 'com.android.support:design:23.2.1'
compile project(':SeekArc_library')
How can i solve this problem ?
I am assuming you are using the standard gradle build tooling and Android Studio.
Below is the recommended solution for issues of clashing dependencies. Eg say you have declared an explicit dependency on com.google.guava version X but some other dependency is bringing its own internal dependency on com.google.guava version X-1.
Add the following after your dependencies clause in the build.gradle file.
configurations {
all*.exclude group: 'com.google.guava', module: 'guava-jdk5'
}
For details see https://docs.gradle.org/current/dsl/org.gradle.api.artifacts.Configuration.html
Note: there is another approach where you may selectively exclude certain dependency from each compile clause but it is not recommended since it doesn't scale well. For completeness I'll include it here but I do not recommend it. Using the same made-up example as above
compile(group: 'com.google.guava', name: 'guava', version: 'X')
compile(group: 'com.some.other.dependency', name: 'foo', version: 'bar')
{
// exclude transitive dependency since we want to depend on version `X` declared above
exclude(group: 'com.google.guava', module: 'guava-jdk5')
}
My App and newly added Library dependencies were in conflict. I changed app compiled & build sdk to api 23 and added "useLibrary 'org.apache.http.legacy'". Now problem solved.
The top level applications library dependency will override the lower level library dependency . You don't need to override explicitly. Refer to Android build documentation
If you want to exclude the dependancies of the library you are using you can
compile 'yourLibraryName'{
exclude module: 'appcompat-v7'
exclude module: 'appcompat-v7'
}
Make sure you provide your own version though, otherwise you'll get runtime errors
I have tried to add a Google Map fragment to my android app. I add the dependency
compile 'com.google.android.gms:play-services-maps:8.1.0'
However when I try to sync the gradle build file I get the error
Warning:Conflict with dependency 'com.android.support:support-annotations'.
Resolved versions for app (22.2.0) and test app (23.0.1) differ.
On the advice of another stack overflow answer we ran the Gradle dependencies report, and found that the only package that includes the module 22.2.0 is the google play one itself.
I have tried to exclude the module but this is to no avail.
Has anyone solved this problem? Any help would be much appreciated.
I attach the relevant part of the build.gradle file
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
//./compile 'com.android.support:appcompat-v7:19.1.0'
androidTestCompile ('com.android.support.test:runner:0.4') {
exclude module: 'support annotations'
}
// Set this dependency to use JUnit 4 rules
androidTestCompile ('com.android.support.test:rules:0.4') {
exclude module: 'support annotations'
}
// Set this dependency to build and run Espresso tests
androidTestCompile ('com.android.support.test.espresso:espresso-core:2.2.1') {
exclude module: 'support annotations'
}
// Set this dependency to build and run UI Automator tests
androidTestCompile 'com.android.support.test.uiautomator:uiautomator-v18:2.1.2'
androidTestCompile 'junit:junit:4.12'
compile 'com.google.android.gms:play-services-maps:8.1.0'
}
You are not excluding the support annotations module from your testing libraries because of a small typo. Change "support annotations" to "support-annotations" in your exclude statements.
exclude module: 'support-annotations'
Huh! Faced this issue in the morning and now seeing this question.
I resolved by adding the following additional dependency:
androidTestCompile 'com.android.support:support-annotations:22.+'
I was not sure of the correct resolving version thereby kept with wildcard '+', if you are sure replace the wildcard with the right one.