I exported my project from Eclipse and imported to Android Studio using the instructions in this link: http://developer.android.com/sdk/installing/migrate.html
When I build, I have an error:
Duplicate files copied in APK META-INF/DEPENDENCIES
After searching, I found a solution: add
packagingOptions {
exclude 'META-INF/DEPENDENCIES'
}
into build.gradle. And it works!
But I don't understand why I had this error and why I've had to apply that fix. Can anybody explain?
While Scott Barta's answer is correct, is lacks a simple and common solution: just add
android {
packagingOptions {
exclude 'META-INF/DEPENDENCIES'
exclude 'META-INF/NOTICE'
exclude 'META-INF/LICENSE'
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/NOTICE.txt'
}
}
to your build.gradle to ignore those duplicates.
In Android Gradle builds, you're not permitted to include the same file with the same path more than once in the output. In your build, there were two META-INF/DEPENDENCIES files coming from different places. Since you don't need this file at all in your application, the simplest thing to do is to tell the build system to ignore it altogether, which is what this exclude directive does.
There's also a pickFirst directive to tell the build system to keep one of the copies; there's a tiny amount of detail on that in Android Gradle plugin 0.7.0: "duplicate files during packaging of APK".
Android builds in Gradle are rather strict about duplicate files, which can make life difficult. There's a similar problem if you include the same Java class more than once, where you get the "Multiple dex files define" error (see Multiple dex files define Landroid/support/v4/accessibilityservice/AccessibilityServiceInfoCompat) for a typical example).
Other build systems are more lenient. It's typical in Java that if you include the same class more than once in a classpath, for example, the first copy it sees is the one that's used; duplicates after that are ignored. This is in most cases easier to deal with, but it has a couple problems. The biggest one is that there can be subtle errors if multiple different versions of a file creep into the build without you knowing -- it can be difficult to figure out what's going on. When you do figure it out, you can usually solve it by juggling the order in which things are included to make sure the one you want makes it to the final output, but in very complex builds, this can be difficult to achieve, and it can happen that doing seemingly unrelated things like including new libraries in your project can upset the ordering and lead to a lot of woe.
For that reason, Gradle has the philosophy of not relying on ordering of things to determine "winners" in the game of resolving duplicates, and it forces the developer to make all dependencies explicit. Android's implementation of its build system on top of Gradle follows that philosophy.
The simplest solution is to add
packagingOptions {
pickFirst 'META-INF/*'
}
to your build.gradle in android section
The easiest way I've found to resolve this problem is to use a wildcard, so you don't find yourself having to manually declare each file in conflict.
packagingOptions {
pickFirst '**'
}
In case that anyone having these problem while uploading new .apk to Google Play Store, after updatng Android Studio ;
click V1 Jar Signature not Full Apk Signature while Generating new Apk with old Keystore
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support:design:27.1.1'
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
implementation 'com.google.android.gms:play-services-ads:10.2.1'
implementation 'com.android.support:support-annotations:25.0.1'
testImplementation 'junit:junit:4.12'
**// select only one in two line below** implementation ‘package’ //implementation project(‘:package’)
}
// good luck
Related
I recently added implementation 'com.google.android.play:core:1.6.4' as a dependency in my android project and now Intellij is complaining that Program type already present: androidx.exifinterface.R. What does this mean and how do I fix this?
Note: this is meant to be a Q&A question. I've already found a solution and I want to share with others.
I recently ran into an issue where android studio would complain that Program type already present: androidx.exifinterface.R. This happened after adding the implementation 'com.google.android.play:core:1.6.4' dependency. I had stumbled on this before with androidx.asynclayoutinflater.R. I've found the that adding something like the following to your module level gradle file will fix it:
configurations.all {
// This is from a previous, similar issue
exclude group: "androidx.asynclayoutinflater", module: "asynclayoutinflater"
// This is the LOC that fixed the issue in this post
exclude group: "androidx.exifinterface", module: "exifinterface"
}
The pattern seems to be:
if there's a complaint about androidx.MODULE_X.R already being present
then add
exclude group: "androidx.MODULE_X", module: "MODULE_X"
to configurations.all in module level gradle file
This worked for both asynclayoutinflater and now exifinterface. I don't know if the pattern scales but so far it has worked. My understanding of the underlying issue is that two dependencies in the module dependency graph (eg com.google.android.play:core) explicitly include the problematic module (eg exifinterface) and so we need to exlude one of those explicit dependencies. My understanding might be wrong.
The gradle docs don't take the time to explain the entities they are dealing with. That's why I want to ask such a basic question.
I've got a to understand in detail, what the terms group, module and artifact really mean to alter this code:
compile('com.thoughtworks.xstream:xstream:1.4.7') {
exclude group: 'xmlpull', module: 'xmlpull'
}
About a year ago I used that exclude statement I took from Android dalvik conversion for xmlpullparser to fix a Multiple dex files failure.
However, after upgrading to Android Studio 3.0 that error occurrs again! Now it says: Multiple dex files define Lorg/xmlpull/mxp1/MXParser and sometimes ...XmlPullParserException.java So, id like to understand how the parameters I give exclude must be shaped.
Reading the documentation one could think a group is the package name and the artifact is the class:
//excluding a particular transitive dependency:
exclude module: 'cglib' //by artifact name
exclude group: 'org.jmock' //by group
exclude group: 'org.unwanted', module: 'iAmBuggy' //by both name and group
Another chinese page (translated) used those excludes
compile ( 'com.thoughtworks.xstream: xstream: 1.4.7' ) {
exclude group : 'xmlpull'
exclude group : 'XmlPullParser'
}
Built on that findings wonder
how xmlpull worked when the package name begins with org.xmlpull?
what projects those terms refer to in my scenario. Where was the group name defined?
What kinda group is XmlPullParser?
Must I clean, rebuild or just build the project after altering those parameters? Because sometimes it complains about different files.
The group, artifact and version are chosen semi randomly and do NOT need to match packages or classes in the jar file.
For example commons-lang has groupId = 'commons-lang' but the classes are in org.apache.commons.lang.* package
The group, artifact and version are defined within the build file of the project. In maven this will be in pom.xml in gradle this will be in build.gradle (and settings.gradle)
If you want to know the group, artifact, version for a project (aka GAV, aka maven co-ordinates) you will usually go to the project's home page.
You can also use the maven central advanced search to "fuzzy" search eg by artifactId or by a classname within a jar. If you are using an in-house repository you can likely "fuzzy" search via the web interface there also
Contrary to many other posts on this topic, I want to exclude a native library from an Android build with Gradle.
libfoo.so resides in a library project in the default directory thelib/src/main/jniLibs. In my main project's build.gradle I try to exlude the file as follows:
sourceSets {
all{
jniLibs {
exclude '**/libfoo.so'
}
}
}
This does not work though, the file is still in the final APK. I tried different path specifications already, but none of them work.
Is this even possible, or is there a workaround?
I know this is an old question, i solved my problem with the following
packagingOptions {
exclude 'lib/arm64-v8a/libfoo.so'
}
Hope it helps someones...
Note:
On further searching someone had already solved a similar issue;
Gradle exclude arm64 libs
When I was trying to use Android Studio to debug my project, I got the following error,
Class com.google.ads.AdRequest.Gender has already been added to output. Please remove duplicate copies.
The cause seems to be that the google play services lib and another lib used by my project both contain the com.google.ads.AdRequest.Gender class, and I don't think I can remove it from either one.
Does anyone know how to fix this problem?
Thanks a lot.
I tried the following statement in build.gradle in order to exclude the duplicated classes in the google play services lib, but it still does not solve the problem.
compile ('com.google.android.gms:play-services:4.1.32') {
exclude group: 'com.google.ads'
}
You can try using Gradle's exclude mechanism when setting up the DatawindAdsSdk-2.0 dependency. There are docs available, but it will probably look something like this:
dependencies {
compile files('libs/datawindAdsSdk-2.0.jar') {
exclude group: 'com.google.ads'
}
}
experiment with that and see if you can get it working.
But I came to this post via google and I read this post has the same problem as me. I solved it excluding the group and the whole library. In my case the problem was with an animatorListener.
compile ('com.rengwuxian.materialedittext:library:1.8.2'){
exclude group: 'com.nineoldandroids', module: 'library'
}
This is my post duplicate library gradle animatorlistener duplicate
I'm using gradle 1.10 and the version of the android plugin is 0.8.0. My android projects needs these two jars: jackson-core-asl-1.9.11.jar and jackson-mapper-asl-1.9.11.jar. I add the files thus:
dependencies {
compile files('libs/jackson-core-asl-1.9.11.jar')
compile files('libs/jackson-mapper-asl-1.9.11.jar')
}
During gradle build I get an error message saying that these two files are duplicated in META-INF/ASL2.0. I solved the problem by excluding the following files:
packagingOptions {
exclude 'META-INF/ASL2.0'
exclude 'META-INF/LICENSE'
exclude 'META-INF/NOTICE'
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/NOTICE.txt'
exclude 'META-INF/notice.txt'
exclude 'META-INF/license.txt'
}
I have to exclude all of them because there apparently is a duplicate file in all of them.
I'd like to know why this problem occurs. Is it a bug of the android plugin or the gradle itself? Can excluding the above files cause any problems? Am I just excluding the above mentioned jars or is there anything else in those META-INF files? I don't want to exclude anything my project needs
First this is not a bug of gradle .
It occurs in MergeJavaResourcesTransform task:
As we know ,APK is just a zip file, so when put META-INFO/xxx into zip file, if file has been added before ,we can not put it again.
And there is no merge rules for META-INFO files , so we can only add on file which names NOTICE etc
Here's some info from the Jackson team https://github.com/FasterXML/jackson-databind/issues/214
There are a variety of posts about this on SO, such as this one: Error generating final archive: Found duplicate file for APK: LICENSE.txt
I've used Jackson with Eclipse and Ant as well (and I'm currently using it in Studio with the same workaround you are using), and I had to use zip on the command to rename the license.txt file. There's more info about the whole thing (including an example of using zip to rename the file) in this post Android Gradle plugin 0.7.0: "duplicate files during packaging of APK".
I have not found anything indicating that renaming or excluding these files will have negative consequences, and I never experienced any problems in about 2 years of using Jackson with Eclipse and Ant.