How do I resolve "Duplicate files copied in APK META-INF/*"
Asked Answered
I

7

92

I am working at a commercial android application. I am also using some libraries licensed under different license types some of them stating the following:

If the library has a "NOTICE" file with attribution notes, you must include that NOTICE when you distribute

(One of them is licensed under Apache License 2.0 for example).

There is more than one library. When I do the build with gradle or with Android Studio I obtain the following build error:

* What went wrong:
Execution failed for task ':app:transformResourcesWithMergeJavaResForDebug'.
> com.android.build.api.transform.TransformException: com.android.builder.packaging.DuplicateFileException: Duplicate files copied in APK META-INF/license.txt

The answers that I found until now on the internet and stackoverflow suggest to remove the license.txt(notice.txt or other files that could interfere like this) from packaging by adding to build.gradle file the following:

packagingOptions {
    exclude 'META-INF/DEPENDENCIES.txt'
    exclude 'META-INF/LICENSE.txt'
    exclude 'META-INF/NOTICE.txt'
    exclude 'META-INF/NOTICE'
    exclude 'META-INF/LICENSE'
    exclude 'META-INF/DEPENDENCIES'
    exclude 'META-INF/notice.txt'
    exclude 'META-INF/license.txt'
    exclude 'META-INF/dependencies.txt'
    exclude 'META-INF/LGPL2.1'
}

See for example: Android Studio 0.4 Duplicate files copied in APK META-INF/LICENSE.txt

According to the license of those libraries(Apache License 2.0 for instance), the license and notice files should be included.

My question: How can I add multiple files related to licensing(such as license.txt, notice.txt etc) from gradle into my project in order to be compliant with the licenses(technical detail: licences texts will be concatenated)?

Ignorance answered 25/11, 2015 at 18:2 Comment(3)
From a technical POV, can you not package things so that all the "must include" files of each library is in their own directory? An alternative I've seen with some apps is for you to (manually) combine all the respective licence/notice files into one resource and include/display this (where two or more libraries share the same licence version, you should be able group them, "Library A and Library B are included subject to the following licence:...").Anacoluthon
@Anacoluthon this is what I currently do as a workaround, while in developing process I exclude them and when it comes to release: comment all 'excludes' and solve the licenses manually.Ignorance
searching for the answer "packagingOptions - exclude" deserves an upvoteEoin
A
48

There is a solution if you have only one license using the name license.txt (read: all license.txt copies are identical):

packagingOptions {
   pickFirst  'META-INF/license.txt'
}

Otherwise, Google also released a Gradle plugin to manage dependencies licenses. See here. I didn't try it, but it looks like it's capable of aggregating every dependency, and even generating an activity displaying all of those licenses.

Adp answered 15/12, 2015 at 11:16 Comment(7)
I have 2 licenses at this moment, one is from Apache 2.0 the other one GPL 3.0. My current workaround is to exclude them while in developing phase and manually include them when we release. All license.txt will be concatenated. Same for notice.txt Anyway I like your approach with pickFirst in case the license is identical!Ignorance
If you ever find a way to automatically concatenate licenses, I'm all ears!Adp
This is what I am investigating now. First I need to find out what(and how) is doing the gradle task that generated the conflict(for that I asked this question: #34288201) And then replace itIgnorance
@Ignorance how you include the all notice.txt manually,just copy them in one notice.txt? can not modify it which in jar fileTransudation
you mention that the issue is in the libraries being used...in my case, I'm responsible for creating the libraries I'm using..what I could be doing wrong when I am making them? ThanksBasilio
@Basilio that's a good question. I can't figure out what I meant by that… I'm removing that part until I can remember. Silly brain :-(Adp
@Ignorance I don't know if you actually found a proper solution, including different licenses with the same file name, but Google released a plugin that might be useful: developers.google.com/android/guides/opensourceAdp
N
32

Add following into respective build.gradle file

packagingOptions {
        exclude 'META-INF/ASL2.0'
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/NOTICE'
        exclude 'META-INF/NOTICE.txt'
        exclude 'META-INF/LICENSE.txt'
        exclude 'META-INF/MANIFEST.MF'
    }
Narra answered 13/4, 2016 at 9:11 Comment(2)
This excludes licenses which, for most of them, is explicitly against their conditions.Adp
This should be in the android{} closure for current (2.*) versions of GradleDielu
O
4

I faced the same issue with my application. You need to make sure you have not added any libraries twice. If you have followed the firebase documentation https://firebase.google.com/docs/android/setup

Then you should not add firebase library inside android studio i.e. file->project structure->cloud->firebase

You have to do only one of the both, to use firebase in your android application.

At the end clean and rerun your app.

Overlap answered 18/7, 2016 at 8:24 Comment(1)
If you use jackson-databind you get the problem when you add it once.Ashram
D
2

As an alternative to Marc Plano-Lesay's answer, you can also merge the files:

packagingOptions {
    merge "META-INF/license.txt"
}

Reference: Gradle API 4.2 Packaging Options

Drusilladrusus answered 18/7, 2021 at 16:11 Comment(1)
This is indeed the correct way to solve this for most people.Etheridge
C
0

You can add multiple licence in gradle see this

Castellan answered 15/12, 2015 at 11:44 Comment(0)
D
0

I think you need to include only these options in build.gradle:

android {
    packagingOptions {
        exclude 'META-INF/DEPENDENCIES.txt'
        exclude 'META-INF/NOTICE'
        exclude 'META-INF/NOTICE.txt'
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/LICENSE.txt'
    }
}
Denitadenitrate answered 4/11, 2017 at 9:51 Comment(0)
J
-2

Surely it will work

packagingOptions {
 exclude 'META-INF/LICENSE.txt'
 exclude 'META-INF/NOTICE.txt'   }
Johnjohna answered 20/4, 2016 at 6:14 Comment(3)
No, it won't: this excludes the licenses. It's illegal according to the said licenses terms.Adp
No its an tmp solution for instant compiling of an projectJohnjohna
Whatever the usage is, read the licences: for a big majority of them, what you're achieving with your exclusion rule is illegal.Adp

© 2022 - 2024 — McMap. All rights reserved.