Duplicate libraries in two different project modules - android

I have project with two modules.
I'm using SalesforceSDK which is included as separate module and inside SalesforceSDK I have Cordova which is using okhttp.
In second module I have retrofit library which is using okhttp too and when I try to build the project I get
duplicate dex files error
I tried to delete okhttp dependency from SalesforceSDK and include it from my second module but I'm getting
symbols not found error
Only thing left to do is to include okhttp as different module but before I do that I want to ask you if there is another way to fix this problem ?
EDIT:
I tried solution proposed by Aayushi but still I get errors :
Error:Execution failed for task
':app:packageAllDebugClassesForMultiDex'.
java.util.zip.ZipException: duplicate entry: com/squareup/okhttp/Address.class

if you are using android studio no need to delete you can use both library
just use
android {
defaultConfig {
...
multiDexEnabled = true
}
}
using this statement is also required
dependencies
{
compile 'com.android.support:multidex:1.0.0'
}

Take a look at jarjar, which can let you use one version of OkHttp in one place and another somewhere else.
There are other similar tools (shade), and most of ‘em will work for you.

I also have another solution for this issue.
Firstly, I run this command line:
and this is result:
I saw that Paypal also use okhttp library.So, I added this line to gradlew:
compile('com.paypal.sdk:paypal-android-sdk:2.13.3')
{
exclude group: 'com.squareup.okhttp3', module: 'okhttp'
}
And It aslo works fine for me.

I was able to fix the issue by following this - https://developer.android.com/studio/build/dependencies#duplicate_classes
In my case, cordova-android-3.3.0.jar was a dependency in 2 different projects and one of those is a dependency of the other one.

Related

Multiple APKs packaging the same library can cause runtime errors with only one dynamic module on AGP 4.0.1?

I have only one dynamic feature module in my project called search, But when I try to build project, I get that Error:
[:search, :search] all package the same library [androidx.recyclerview:recyclerview].
Multiple APKs packaging the same library can cause runtime errors.
Placing each of the above libraries in its own dynamic feature and adding that
feature as a dependency of modules requiring it will resolve this issue.
Libraries that are always used together can be combined into a single feature
module to be imported by their dependents. If a library is required by all
feature modules it can be added to the base module instead.
Of Course, the first thing I did is to research about people who had the same problem And I found:
1- This Question
2- This medium article
Both Introduce the same solution (Use Android Gradle Plugin 4.0) and my project uses AGP 4.0.1, But the problem is that I have only one dynamic module called search. I don't have any other dynamic modules, even further I don't have the dependency of RecyclerView: androidx.recyclerview:recyclerview in my search gradle file, So this is maybe a transitive dependency.
Also, you can find that duplicated dependency in one of two ways:
1-Navigate to: PROJECT_NAME/module_name(In my case: search)/build/intermediates/
and then search for "deps.txt" file in that directory, Open the file and you will see all your module dependencies direct and transitive ones
2- run ./gradlew :module_name:dependencies task
If you tried to remove that duplicated line: androidx.recyclerview:recyclerview from "deps.txt" file, it gets generated again after each build.
That being said, I need some rule in my packagingOptions {} like exclude to prevent that conflict between search.aar and and any other search.* format
Can anyone help, please?
In my case, I removed the below from one of the modules
Note: not from the base module
implementation 'androidx.legacy:legacy-support-v4:1.0.0'

R8: Program type already present: androidx.databinding.library.baseAdapters.BR

Im getting the above error trying to create a release build of my app. When doing a debug build everything is running fine.
My project has a structure as follows
app (contains databinding)
video sdk (contains data binding)
another sdk (contains data binding)
Im thinking it finds multiple databinding instances which makes the above error but im not really sure how to circumvent this.
What also weird is that the app does compile when clicking run in Android studio but when trying to build from terminal its not compiling
Posting few of workarounds here
./gradlew clean
Exclude duplicates as message Program type already present means there is a naming conflict.
configurations {
compile.exclude group: 'androidx.databinding', module: 'databinding'
}
Then do sync, clean & rebuild.
I am not sure but tried to create a separate module for databinding gradle and add that module into all current modules (app, video sdk, another sdk)
Module core (Gradle with "api"):
api 'com.github.bumptech.glide:glide:4.9.0'
kapt 'com.github.bumptech.glide:compiler:4.9.0'
App module and other SDKs modules will use that core module.
implementation project(path: ':core')
Hope it will help.
I faced this error and spent almost 2 days in figuring out what was causing this error. Eventually, I found out that one of my transitive SDK, which used Kotlin, did not have the following in its Gradle file.
kotlinOptions kotlin_options = {
jvmTarget = "1.8"
}
After adding this, I was able to resolve the error.
Please try this, I am not sure but sometime release apk having problem of conflict ion
Add multiDexEnabled true in app gradle file.
Hope this will help!

How to use only one library (are multiple same ones)

Situation is that I in my project use library A. I also import external library which also has itself a library A. So as you can assume, when I try to compile, I receive Multiple DEX files define error which means that there are duplications.
However, If I remove my library from the project, I cannot use its provided methods. And I cannot find how can I remove that library from the module.
Any suggestions?
You should be able to exclude it like this:
compile('library:1.0.0') {
exclude group: 'something', module: 'something'
}
So do this on the external library for all the things you're using that's causing a problem.
From here: https://discuss.gradle.org/t/how-to-exclude-transitive-dependency/2119/2
define multiDexEnable True in your build.gradle(app)
defaultConfig {
multiDexEnabled true
}
and also define in dependency in same build.gradle(app)
compile 'com.android.support:multidex:1.0.1'
Thank you guys for your suggestions.
I didn't want to do as Michael suggested because I believe it is kind of useless (having multiple libraries with same purpose) (already knew this trick).
I have tried Ядм Жцмдшдт answer, but couldn't succeed in compiling code completely. I have received various errors.
In the end I have solved my own issue. What I did:
Remove library from my main app libs folder. Remove dependancies if any in Android Studio (File -> Project Structure -> Dependencies (On module app) -> remove if any regarding your library.
Clean project in Android Studio (Build -> Clean Project).
Go to the module where my library A is. Go to that module build.gradle file and add following line in the dependencies cluster
compile files('libs/libraryA.jar')
Sync code and enjoy results.
TLDR
I didn't have libraryA compiled in my external module but it threw me duplication error, that's where I was confused. By removing it from my main project and adding it to my module's compilations list solved the problem.

Android Studio: Resolving Duplicate Classes

When I try to run my android application on an Android device, the gradle console reports the following error:
Error:Execution failed for task ':app:transformClassesWithJarMergingForDebug'.
> com.android.build.api.transform.TransformException: java.util.zip.ZipException: duplicate entry: com/loopj/android/http/AsyncHttpClient$1.class
When I search for the "AsyncHttpClient" class, I see that it's indeed being found in two separate locations:
/Users/Afflatus/.gradle/caches/modules-2/files-2.1/com.loopj.android/android-async-http/1.4.9/5d171c3cd5343e5997f974561abed21442273fd1/android-async-http-1.4.9-sources.jar!/com/loopj/android/http/AsyncHttpClient.java
/Users/Afflatus/.ideaLibSources/android-async-http-1.4.9-sources.jar!/com/loopj/android/http/AsyncHttpClient.java
The first path seems to suggest it's a "cache" file... so I've tried invalidating & restarting my cache, but both files are still there after the gradle gets rebuilt and I try to run the application. I've read in alternate posts that it can be resolved by deleting one of the files... So I went to the cache location and deleted all the files found in the "1.4.9" folder... unfortunantly after reopening Android Studio, a new cache file gets created and I get the same error.
Other posts (here, here,here, and here) suggest if I add "./gradlew clean" to the root directory it would rebuild the gradle again just for the run (as far as I understand). So I tried doing that as well:
Which made my app's folder look like this:
But unfortunantly, that didn't help things I still get the same error. What am I doing wrong? What should I be doing?
I added this line to my gradle.properties file and my app worked
android.enableJetifier=true
Sometimes duplicate classes exception means that one of your dependencies uses implicitly the older or newer (with +) version of some library you also use in your project,
To resolve this issue you may add such block of code (put your library version after 'force') to your build.gradle file (Module:app):
configurations {
all {
resolutionStrategy {
// do not upgrade above 3.12.0 to support API < 21 while server uses
// COMPATIBLE_TLS, or okhttp3 is used in project
force 'com.squareup.okhttp3:okhttp:3.12.0'
force 'com.squareup.okhttp3:logging-interceptor:3.12.0'
}
}
}
You may also exclude some group from your dependencies.
For a single dependency you way write:
dependencies {
// example
implementation('log4j:log4j:1.2.15') {
exclude group: 'javax.jms', module: 'jms'
}
}
Tested to work on Android Studio with Gradle Plugin version 3.4.2 and Gradle version 5.4.1.
Credits go to Dimitar Dimitrov and Schalk Cronjé from gradle org discussion group
That's because you have added some library two times in libs folder, this could happen sometimes when you have multiple versions of the same library in the libs folder. Check it and remove any duplicate jar files.
And the second option could be you have also added the dependency in gradle.build and also have a jar in libs folder.
So check both places and remove duplicate entries and then clean and build APK again.
Delete files with duplicate jar extensions in the libs folder. However, if there are no duplicate files and there is still a "Duplicate classes" error, look for the name in the rest of the "Duplicate classes ...." clause in the error section. For example, "duplicated classes 'dagger' bla bla". Delete the file named 'dagger' from the libs folder. (Be careful not to delete it with shift.)
In my case, I am using sensorocloud.jar and the compile 'com.loopj.android:android-async-http:1.4.9' in my gradle which caused the same error as yours. Because sensoro cloud SDK used loopj's async-http.
I managed to solve it by manually removing the duplicate .class files in the jar file. (i.e.
changing the extension from jar to zip
extract it
remove the com.loopj.android .class files)
(P.S. I have tried to search through the web to see if I could exclude certain class of a jar in gradle, but not succeed, e.g. I referenced this SO post)
This error can be caused by several things;
misconfigured package name
Activity views that is not well binded. - simply go to your launcher activity view and ensure context is defined well e.g "com.yourdomain.package"
Re-create your BuildConfig and set it up well.
Check if your project build.gradle. There it might be some maven duplicate dependency
Here's another situation that can cause duplicate class during the mergeDexClasses task. This can happen with later versions of android gradle.
If your build.gradle.kts script has a dependency in the form:
implementation(project(":mylib", configuration="default"))
that can cause duplicate classes. The correction is simple. Just change it to:
implemenation(project(:mylib"))
Here's the Android Studio's Team explanation:
Having both project(":lib") and project(path: ":lib", configuration: "default") in the runtime classpath means that AGP gets both build/classes/java/main and build/libs/lib.jar (run ./gradlew :lib:outgoingVariants --all to verify). Because paths differ, we'll get 2 dexing transforms happening: 1 incremental that produces dex per class under build/.transforms (the one processing dir) and another one which produces single dex (the one processing jar). Later on during merging this causes failure.
AGP never publishes to the default configuration, in fact java-library plugin does it only so it does not break older build scripts. Having an explicit configuration name used in the dependency declaration is discouraged and Gradle attributes should be used instead.
In an older version of AGP, I ran into a problem where adding the configuration value "default" fixed some issue I was having. Well that no longer works, and adding the "default" configuration you can get duplicate classes.

Duplicate zip entry [okhttp-2.4.0.jar:com/squareup/okhttp/Address.class]

I have android multi-project setup with okhttp as part of multiple projects
In project A, okhttp is included in the source code.
In project B, okhttp comes with part of a library dependency.
When I build, I get the below error.
Execution failed for task ':Events-Android:events:proguardFlavDebug'.
java.io.IOException: Can't write [/Users/gatorboy/events/Events-Android/events/build/intermediates/classes-proguard/dfmobile/debug/classes.jar] (Can't read [/Users/gatorboy/.gradle/caches/modules-2/files-2.1/com.squareup.okhttp/okhttp/2.4.0/40340c0748190fe897baf7bffbc1b282734294e5/okhttp-2.4.0.jar(;;;;;;!META-INF/MANIFEST.MF)] (Duplicate zip entry [okhttp-2.4.0.jar:com/squareup/okhttp/Address.class]))
I couldnt exclude okhttp from Project B as it is a different version compared to the okhttp source code in Project A. Is there any other way to resolve this issue?
There are similar posts on stackoverflow but I couldn't find a solution.
I got same error. Just add these line to build.gradle and it works for me !
configurations{
all*.exclude module: 'okhttp'
all*.exclude module: 'okio'
}
You can't have two versions of the same library in the same application. If you ABSOLUTELY need two versions of the same library then you need to repackage one of the versions using the jarjar tool.
Otherwise your never going to get two different versions of the same lib into the same app.
Best fix is to use the same version for both packages... if that's not an option then jarjar repackaging is the only solution, but it's not a good solution as the lib must be manually repackaged again if you need a different version later.
JarJar reference: https://code.google.com/p/jarjar/

Categories

Resources