¿Cómo resuelvo "archivos duplicados copiados en APK META-INF / *"

91

Estoy trabajando en una aplicación comercial de Android. También estoy usando algunas bibliotecas con licencias de diferentes tipos de licencias, algunas de las cuales indican lo siguiente:

Si la biblioteca tiene un archivo de "AVISO" con notas de atribución, debe incluir ese AVISO cuando distribuya

(Uno de ellos tiene la licencia Apache License 2.0, por ejemplo).

Hay más de una biblioteca. Cuando hago la compilación con gradle o con Android Studio, obtengo el siguiente error de compilación:

* 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

Las respuestas que encontré hasta ahora en Internet y stackoverflow sugieren eliminar el license.txt (aviso.txt u otros archivos que podrían interferir como este) del paquete agregando al build.gradlearchivo lo siguiente:

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

Ver, por ejemplo: Android Studio 0.4 Archivos duplicados copiados en APK META-INF / LICENSE.txt

De acuerdo con la licencia de esas bibliotecas ( Apache License 2.0, por ejemplo), se deben incluir los archivos de licencia y aviso .

Mi pregunta: ¿Cómo puedo agregar varios archivos relacionados con las licencias (como license.txt , notice.txt , etc.) de gradle en mi proyecto para cumplir con las licencias ( detalle técnico: los textos de las licencias se concatenarán)?

Flowryn
fuente
2
Desde un punto de vista técnico, ¿no se pueden empaquetar las cosas para que todos los archivos "obligatorios" de cada biblioteca estén en su propio directorio? Una alternativa que he visto con algunas aplicaciones es que (manualmente) combine todos los archivos de licencia / aviso respectivos en un recurso e incluya / muestre esto (donde dos o más bibliotecas comparten la misma versión de licencia, debería poder agruparlas , "La biblioteca A y la biblioteca B están incluidas sujetas a la siguiente licencia: ...").
TripeHound
@TripeHound esto es lo que hago actualmente como solución alternativa, mientras que en el proceso de desarrollo los excluyo y cuando se trata de liberarlos: comentar todos los 'excluidos' y resolver las licencias manualmente.
Flowryn
1
buscando la respuesta "packagingOptions - exclude" merece un voto a favor
Ahmed Adel Ismail

Respuestas:

47

Existe una solución si solo tiene una licencia con el nombre license.txt(lea: todas las license.txtcopias son idénticas):

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

De lo contrario, Google también lanzó un complemento de Gradle para administrar licencias de dependencias. Vea aquí . No lo probé, pero parece que es capaz de agregar todas las dependencias e incluso generar una actividad que muestre todas esas licencias.

Marc Plano-Lesay
fuente
1
Tengo 2 licencias en este momento, una es de Apache 2.0 y la otra GPL 3.0. Mi solución alternativa actual es excluirlos mientras están en la fase de desarrollo e incluirlos manualmente cuando lancemos. Se concatenará todo el archivo license.txt. Lo mismo para notice.txt De todos modos, me gusta su enfoque con pickFirst en caso de que la licencia sea idéntica.
Flowryn
3
Si alguna vez encuentra una manera de concatenar licencias automáticamente, ¡soy todo oídos!
Marc Plano-Lesay
Esto es lo que estoy investigando ahora. Primero necesito averiguar qué (y cómo) está haciendo la tarea de Gradle que generó el conflicto (para eso hice esta pregunta: stackoverflow.com/questions/34287701/… ) Y luego reemplazarla
Flowryn
@Flowryn, ¿cómo incluyes todos los avisos.txt manualmente, solo cópialos en un aviso.txt? no se puede modificar lo que en el jararchivo
chinaanihchen
mencionas que el problema está en las bibliotecas que se están utilizando ... en mi caso, soy responsable de crear las bibliotecas que estoy usando ... ¿qué podría estar haciendo mal cuando las estoy creando? Gracias
Eric
32

Agregue lo siguiente en el archivo build.gradle respectivo

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'
    }
Max Droid
fuente
1
Esto excluye las licencias que, para la mayoría de ellos, están explícitamente en contra de sus condiciones.
Marc Plano-Lesay
1
Esto debería estar en el cierre de Android {} para las versiones actuales (2. *) de Gradle
mijiturka
4

Enfrenté el mismo problema con mi solicitud. Debe asegurarse de no haber agregado ninguna biblioteca dos veces. Si ha seguido la documentación de firebase https://firebase.google.com/docs/android/setup

Entonces no debe agregar la biblioteca de base de fuego dentro de Android Studio, es decir, archivo-> estructura del proyecto-> nube-> base de fuego

Tienes que hacer solo uno de los dos para usar firebase en tu aplicación de Android.

Al final, limpia y vuelve a ejecutar tu aplicación.

un poderoso
fuente
2
Si usa jackson-databind, aparece el problema cuando lo agrega una vez.
El increíble
0

Puede agregar varias licencias en gradle ver esto

Akhil Jayakumar
fuente
0

Creo que necesitas incluir solo estas opciones en 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'
    }
}
S.sadham hussain
fuente
-2

Seguramente funcionará

packagingOptions {
 exclude 'META-INF/LICENSE.txt'
 exclude 'META-INF/NOTICE.txt'   }
Caramelo Mahendran
fuente
1
No, no lo hará: esto excluye las licencias. Es ilegal de acuerdo con los términos de licencia mencionados.
Marc Plano-Lesay
No, es una solución tmp para la compilación instantánea de un proyecto
Mahendran Candy
1
Cualquiera que sea el uso, lea las licencias: para la gran mayoría de ellas, lo que está logrando con su regla de exclusión es ilegal.
Marc Plano-Lesay