如何解决“在APK META-INF / *中复制的重复文件”


91

我在一个商业android应用程序上工作。我还使用了一些使用不同许可类型许可的库,其中一些声明如下:

如果库中有带有归因说明的“ NOTICE”文件,则在分发时必须包括该NOTICE

(例如,其中之一已获得Apache License 2.0许可)。

有多个库。使用gradleAndroid 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

到目前为止,我在Internet和stackoverflow上找到的答案建议通过将build.gradle以下内容添加到文件中,将license.txt(notice.txt或其他可能会干扰到此的文件)从打包中删除:

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),应包括许可证和通知文件。

我的问题: 如何从gradle中将与许可相关的多个文件(例如license.txtnotice.txt等)添加到我的项目中,以便与许可兼容(技术细节:许可文本将串联在一起)?


2
从技术角度来看,您是否可以打包内容,以使每个库的所有“必须包含”文件都位于其自己的目录中?我在某些应用程序中看到的另一种方法是让您(手动)将所有各自的许可证/通知文件合并到一个资源中,并包含/显示该资源(其中两个或多个库共享相同的许可证版本,您应该能够将它们分组,“包括图书馆A和图书馆B,但必须获得以下许可:...”)。
TripeHound

@TripeHound,这是我目前作为解决方法所采取的措施,而在开发过程中,我将其排除在发行版之外:注释所有“排除”并手动解决许可证。
Flowryn

1
寻找答案“ packagingOptions-exclude”值得投票
Ahmed Adel Ismail

Answers:


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
如果您找到一种自动连接许可证的方法,我将不知所措!
Marc Plano-Lesay 2015年

这就是我现在正在调查的内容。首先,我需要找出正在发生冲突的gradle任务(以及如何做)(为此,我提出了以下问题:stackoverflow.com/questions/34287701/…),然后将其替换
Flowryn

@Flowryn如何手动添加所有notice.txt,只需将它们复制到一个notice.txt中?无法修改jar文件中的内容
chinaanihchen 2016年

您提到问题出在正在使用的库中...就我而言,我负责创建正在使用的库..制造它们时我可能做错了什么?谢谢
埃里克

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
对于当前(2. *)版本的Gradle,此文件应位于android {}闭包中
mijiturka,2015年

4

我的应用程序遇到了同样的问题。您需要确保没有两次添加任何库。如果您已遵循Firebase文档 https://firebase.google.com/docs/android/setup

然后,您不应该在android studio中添加firebase库,即file-> project structure-> cloud-> firebase

您只需要做这两者之一,即可在Android应用程序中使用firebase。

最后,清理并重新运行您的应用程序。


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
不,不会:不包括许可证。根据上述许可条款,这是非法的。
Marc Plano-Lesay

它没有用于即时编译项目的tmp解决方案
Mahendran Candy

1
无论有什么用途,请阅读许可证:对于大多数许可证来说,使用排除规则所获得的成就是非法的。
Marc Plano-Lesay
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.