custom library: how to handle dependencies? - android

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

Related

Dagger Annotation Processor fails to find com/google/common/collect/SetMultimap

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

Error when adding new dependency to Gradle file?

My build.gradle file:
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile 'com.android.support:appcompat-v7:23.4.0'
compile 'com.google.android.gms:play-services-location:9.4.0'
compile 'com.android.support:design:23.4.0'
compile 'com.github.pwittchen:weathericonview:1.1.0'
compile 'com.jakewharton:butterknife:8.3.0'
compile 'com.android.support:support-v4:23.4.0'
testCompile 'junit:junit:4.12'
apt 'com.jakewharton:butterknife-compiler:8.3.0'
compile 'com.android.support.constraint:constraint-layout:1.0.0-beta4'
compile 'me.everything:overscroll-decor-android:1.0.3'
}
Adding this dependency 'com.github.paolorotolo:appintro:4.1.0' to the gradle file redlines this part 'com.android.support:appcompat-v7:23.4.0' from my gradle file and gives this following error:
All com.android.support libraries must the exact same specification. Found versions 24.2.1, 23.4.0
What does this mean? How do I avoid this conflict when adding that dependency?
It means that the new appintro dependency adds a sub-dependency on the support library, v24.2.1, but you already have an earlier one.
Update your direct dependency to the same version, which in practice will probably be fine, or you'll need to use an older version of appintro that in turn uses an earlier version of the support library.
That is, in the case of the former, change your line to:
com.android.support:appcompat-v7:24.2.1
Edit: I say 'probably fine', because the Android support library is a very stable set of APIs and continues to perform consistently across versions. Outside of that, often when a version change is required, you need to assess whether there are any breaking changes or altered behaviours.

Android app and library dependencies clash

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

Compiling com.parse:parsefacebookutils leads to com.parse.Parse Class not found exception

I'm currently trying to add Facebooklogin capabilites to my App.
According to the Android Docs, when I add
compile 'com.parse:parsefacebookutils-v4-android:1.10.3#aar'
To my Build.gradle it should include the entire com.parse.Parse, com.parse.ParseObject... classes already. So I removed the compile for the normale parse-android and now my dependencies look like that:
compile fileTree(include: ['*.jar'], dir: 'libs')
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.1.1'
compile 'com.android.support:design:23.1.1'
compile 'com.android.support:support-v4:23.1.1'
compile 'com.android.support:recyclerview-v7:23.1.1'
compile 'com.google.android.gms:play-services-auth:8.3.0'
compile 'com.parse:parsefacebookutils-v4-android:1.10.3#aar'
//compile 'com.parse:parse-android:1.10.3' //Already include in parsefacebookutils
compile 'com.facebook.android:facebook-android-sdk:4.7.0'
//NOTE: I do not actually have anything in my 'libs' folder.
BUT after doing so my Applicationclass (and every other Class) can't find the com.parse.Parse stuff. And the com.parse namespace only contains the 'ParseFacebookUtils' class.
I already tried:
compiling the 'com.parse:parse-android:1.10.3' in the dependencies, which only leads to the expected 'DexError' when deploying.
Removing the #aar at the end, which imported the com.parse namespace correctly, but lead to the Gradle error. I assume because the facebookutils have the parse-android:1.10.3 as dependency in their maven project. (http://mvnrepository.com/artifact/com.parse/parsefacebookutils-v4-android/1.10.3)
Warning:Module 'com.parse:parsefacebookutils-v4-android:1.10.3' depends on one or more Android Libraries but is a jar
sounds like there is a bug in the parsefacebookutils that is loaded. I can't say what it is but work around is that download the latest jar files and use them instead of loading.
Parse-1.11.0
ParseFacebookUtilsV4-1.10.3
those .jar files in library directory and remove the compile rows from build.gradle.
at least I'm getting forward with this.

Multi dex files define Lcom/google/gdata/util/common/base/Escaper

Multi dex files define Lcom/google/gdata/util/common/base/Escaper
I am stuck with the above error. The error ocured after i have added a dependency to the UserVoice SDK
compile 'com.uservoice:uservoice-android-sdk:+'
since i added this dependency i am unable to run my Android project.
I have read about the jarjar command could probably solve this issue. But since the dependency are .aar librararies i do not know what could be the possible solution
any help is greatly appreciated
List of other depedencies:
compile('com.crashlytics.sdk.android:crashlytics:2.1.0#aar') {
transitive = true;
}
compile('com.twitter.sdk.android:twitter:1.1.0#aar') {
transitive = true;
}
compile 'com.android.support:support-v4:21.0.0'
compile 'com.android.support:appcompat-v7:20.+'
compile 'com.google.android.gms:play-services-wearable:+'
compile 'com.github.manuelpeinado.fadingactionbar:fadingactionbar-abc:3.1.2'
compile 'com.squareup.retrofit:retrofit:1.7.1'
compile 'com.squareup.okhttp:okhttp-urlconnection:2.0.0'
compile 'com.squareup.okhttp:okhttp:2.0.0'
compile 'com.jakewharton:butterknife:5.1.2'
compile 'com.squareup.picasso:picasso:2.3.4'
compile 'com.melnykov:floatingactionbutton:1.0.5'
compile 'com.balysv.materialmenu:material-menu-abc:1.+'
compile 'de.keyboardsurfer.android.widget:crouton:1.8.5#aar'
compile 'com.facebook.android:facebook-android-sdk:3.20.0'
compile 'com.joanzapata.android:android-iconify:1.0.8'
compile 'com.squareup:otto:1.3.5'
compile 'com.android.support:recyclerview-v7:21.+'
compile 'com.android.support:cardview-v7:21.+'
Gradle depdencies pastebin: http://pastebin.com/0m6b8Wyi
The problem you are having is caused by the fact that you have two dependencies that include the Escaper class. These are most likely dependencies of your dependencies so it's not obvious which one includes that class. You can be sure that com.uservoice:uservoice-android-sdk:+ includes the class Escaper as that is when your error occurs.
You can fix this problem by excluding the dependency from one of your compile dependencies. Take a look at the Gradle docs and scroll down to where it talks about "Excluding transitive dependencies". One thing to be careful of is the fact that the dependencies might be different versions but contain the same class. You should confirm that both libraries will work with the same version of the Escaper class.

Categories

Resources