Как решить проблему «Дубликаты файлов, скопированных в APK META-INF / *»

91

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

Если в библиотеке есть файл «УВЕДОМЛЕНИЕ» с примечаниями об авторстве, вы должны включить это УВЕДОМЛЕНИЕ при распространении

(Один из них, например, находится под лицензией Apache License 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, предлагают удалить файл license.txt (notice.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, в мой проект, чтобы соответствовать лицензиям ( техническая деталь: тексты лицензий будут объединены)?

Flowryn
источник
2
С технической точки зрения, нельзя ли упаковать вещи так, чтобы все «обязательные» файлы каждой библиотеки находились в их собственном каталоге? Альтернатива, которую я видел с некоторыми приложениями, - это (вручную) объединить все соответствующие файлы лицензий / уведомлений в один ресурс и включить / отобразить это (если две или более библиотеки используют одну и ту же версию лицензии, вы должны иметь возможность сгруппировать их , «Библиотека A и библиотека B включены в соответствии со следующей лицензией: ...»).
TripeHound
@TripeHound - это то, что я сейчас делаю в качестве обходного пути, в процессе разработки я исключаю их, а когда дело доходит до выпуска: прокомментируйте все «исключаемые» и решайте лицензии вручную.
Flowryn
1
поиск ответа «PackagingOptions - exclude» заслуживает положительного голоса
Ахмед Адель Исмаил

Ответы:

47

Есть решение, если у вас есть только одна лицензия, использующая имя license.txt(читай: все license.txtкопии идентичны):

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

В противном случае Google также выпустил плагин Gradle для управления лицензиями зависимостей. Смотрите здесь . Я не пробовал, но похоже, что он способен агрегировать все зависимости и даже генерировать действие, отображающее все эти лицензии.

Марк Плано-Лесе
источник
1
На данный момент у меня есть 2 лицензии, одна от Apache 2.0, другая GPL 3.0. Мой текущий обходной путь - исключить их на этапе разработки и вручную включить их при выпуске. Все файлы license.txt будут объединены. То же самое и для notice.txt В любом случае мне нравится ваш подход с pickFirst, если лицензия идентична!
Flowryn
3
Если вы когда-нибудь найдете способ автоматического объединения лицензий, я всем внимателен!
Марк Плано-Леси
Это то, что я сейчас исследую. Сначала мне нужно выяснить, что (и как) выполняет задачу gradle, которая породила конфликт (для этого я задал этот вопрос: stackoverflow.com/questions/34287701/… ), а затем заменить его
Flowryn
@Flowryn, как включить все файлы notice.txt вручную, просто скопировать их в один файл notice.txt? не могу изменить его, который находится в jarфайле
chinaanihchen 03
вы упомянули, что проблема в используемых библиотеках ... в моем случае я отвечаю за создание библиотек, которые использую ... что я могу делать неправильно, когда делаю их? Спасибо
Эрик
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
Сюда не входят лицензии, которые для большинства из них явно противоречат их условиям.
Marc Plano-Lesay
1
Это должно быть в закрытии android {} для текущих (2. *) версий Gradle
mijiturka
4

Я столкнулся с той же проблемой с моим приложением. Вам нужно убедиться, что вы не добавляли библиотеки дважды. Если вы следовали документации firebase https://firebase.google.com/docs/android/setup

Тогда вам не следует добавлять библиотеку firebase внутри студии Android, т.е. файл-> структура проекта-> облако-> firebase

Вам нужно сделать только одно из обоих, чтобы использовать firebase в своем приложении для Android.

В конце очистите и перезапустите приложение.

могучий
источник
2
Если вы используете jackson-databind, вы столкнетесь с проблемой, если добавите его один раз.
Невероятный
0

Вы можете добавить несколько лицензий в gradle, см. Это

Ахил Джаякумар
источник
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
Нет, не будет: сюда не входят лицензии. Это незаконно согласно условиям указанных лицензий.
Marc Plano-Lesay,
Нет, это временное решение для мгновенной компиляции проекта
Махендран Кэнди
1
Каким бы ни было использование, прочтите лицензии: для большинства из них то, что вы достигли с помощью правила исключения, является незаконным.
Marc Plano-Lesay