Як вирішити проблему “Повторювані файли, скопійовані в APK META-INF / *”


91

Я працюю в комерційному додатку для Android. Я також використовую деякі бібліотеки, ліцензовані за різними типами ліцензій, деякі з них зазначають наступне:

Якщо у бібліотеці є файл "NOTICE" із примітками про атрибуцію, ви повинні включити це NOTICE під час розповсюдження

(Один з них ліцензований за ліцензією Apache 2.0 ).

Існує не одна бібліотека. Коли я будую збірку за допомогою gradle або за допомогою Android Studio, я отримую таку помилку збірки:

* 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

Відповіді, які я до цього часу знаходив в Інтернеті та stackoverflow, пропонують вилучити ліцензію.txt (повідомлення.txt або інші файли, які можуть втручатися подібним чином) з упаковки, додавши до build.gradleфайлу наступне:

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

Див. Наприклад: Android Studio 0.4 Повторювані файли, скопійовані в APK META-INF / LICENSE.txt

Відповідно до ліцензії цих бібліотек (наприклад, Apache License 2.0 ), файли ліцензії та повідомлень повинні бути включені .

Моє запитання: Як я можу додати кілька файлів, пов’язаних з ліцензуванням (наприклад, license.txt , notice.txt тощо) з gradle, у свій проект, щоб відповідати ліцензіям ( технічна деталь: тексти ліцензій будуть об’єднані)?


2
З технічного POV, чи не можете ви упакувати речі так, щоб усі файли кожної бібліотеки "повинні містити" знаходились у їхньому власному каталозі? Альтернатива, яку я бачив з деякими програмами, полягає в тому, щоб ви (вручну) об’єднали всі відповідні файли ліцензій / повідомлень в один ресурс і включили / показали це (де дві або більше бібліотек мають однакову версію ліцензії, ви зможете їх згрупувати) , "Бібліотека A та Бібліотека B включені за умови відповідної ліцензії: ...").
TripeHound

@TripeHound це те, що я зараз роблю як обхідний шлях, тоді як у процесі розробки я виключаю їх, а коли справа доходить до випуску: коментуйте всі "виключає" та вирішуйте ліцензії вручну.
Флоурін

1
пошук відповіді "упаковка варіантів
Ахмед Адель Ісмаїл

Відповіді:


47

Є рішення, якщо у вас є лише одна ліцензія з використанням імені license.txt(читайте: всі license.txtкопії ідентичні):

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

В іншому випадку Google також випустив плагін Gradle для управління ліцензіями залежностей. Дивіться тут . Я не пробував, але схоже, він здатний агрегувати кожну залежність і навіть генерувати діяльність, що відображає всі ці ліцензії.


1
На даний момент у мене 2 ліцензії, одна від Apache 2.0, інша - GPL 3.0. Моє поточне обхідне рішення - виключити їх на стадії розробки та включити вручну, коли ми випускаємо. Усі ліцензії.txt будуть об’єднані. Те саме для notice.txt У будь-якому випадку мені подобається ваш підхід з pickFirst, якщо ліцензія ідентична!
Флоурін

3
Якщо ви коли-небудь знайдете спосіб для автоматичного об'єднання ліцензій, я все вуха!
Марк Плано-Лесей

Це те, що я зараз досліджую. Спочатку мені потрібно з’ясувати, що (і як) виконує завдання gradle, що породило конфлікт (для цього я поставив це питання: stackoverflow.com/questions/34287701/… ), а потім
замінюю

@Flowryn, як ви включаєте всі повідомлення.txt вручну, просто скопіюйте їх в одне повідомлення.txt? не можу змінити це, що у jarфайлі
chinaanihchen

ви згадуєте, що проблема полягає в використовуваних бібліотеках ... у моєму випадку я відповідаю за створення бібліотек, якими я користуюсь .. що я можу робити неправильно, коли їх роблю? Дякую
Ерік

32

Додайте наступне у відповідний файл build.gradle

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

1
Це виключає ліцензії, які для більшості з них явно суперечать їх умовам.
Марк Плано-Лесей

1
Це має бути в закритті для Android {} для поточних (2. *) версій Gradle
mijiturka

4

Зі своєю заявкою я зіткнувся з такою ж проблемою. Потрібно переконатися, що двічі не додавали жодної бібліотеки. Якщо ви дотримувались документації Firebase https://firebase.google.com/docs/android/setup

Тоді вам не слід додавати бібліотеку firebase всередину android studio, тобто файл-> структура проекту-> хмара-> firebase

Вам потрібно зробити лише одне з обох, щоб використовувати firebase у вашому додатку для Android.

В кінці очистіть і повторно запустіть програму.


2
Якщо ви використовуєте jackson-databind, ви отримуєте проблему, додавши її один раз.
Неймовірний


0

Я думаю, що вам потрібно включити лише такі параметри в 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'
    }
}

-2

Звичайно, це спрацює

packagingOptions {
 exclude 'META-INF/LICENSE.txt'
 exclude 'META-INF/NOTICE.txt'   }

1
Ні, не буде: це виключає ліцензії. Це протизаконно відповідно до зазначених ліцензійних умов.
Марк Плано-Лесей

Немає рішення TMP для миттєвого складання проекту
Mahendran Candy

1
Яким би не було використання, прочитайте ліцензії: для більшості з них те, що ви досягаєте своїм правилом виключення, є незаконним.
Марк Плано-Лесай
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.