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

Posted

技术标签:

【中文标题】如何解决“在 APK META-INF/* 中复制的重复文件”【英文标题】:How do I resolve "Duplicate files copied in APK META-INF/*" 【发布时间】:2016-02-28 15:40:59 【问题描述】:

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

如果图书馆有一个带有归属说明的“通知”文件,您必须在分发时包含该通知

(例如,其中一个是根据 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 和 *** 上找到的答案建议通过将以下内容添加到 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 Duplicate files copied in APK META-INF/LICENSE.txt

根据这些库的许可(例如Apache License 2.0),应该包含许可和通知文件。 p>

我的问题:如何从 gradle 添加多个与许可相关的文件(例如 license.txtnotice.txt 等)进入我的项目以符合许可证(技术细节:许可证文本将被连接)?

【问题讨论】:

从技术角度来看,你能不能不打包东西,让每个库的所有“必须包含”的文件都在自己的目录中?我在某些应用程序中看到的另一种方法是(手动)将所有相应的许可证/通知文件组合到一个资源中并包含/显示它(如果两个或多个库共享相同的许可证版本,您应该能够将它们分组, "库 A 和库 B 包含在以下许可证中:...")。 @TripeHound 这是我目前作为解决方法所做的,在开发过程中我将它们排除在外,在发布时:评论所有“排除”并手动解决许可证。 寻找答案“packagingOptions - exclude”值得一票 【参考方案1】:

作为 Marc Plano-Lesay 的答案的替代方案,您还可以合并文件:

packagingOptions 
    merge "META-INF/license.txt"

参考:Gradle API 4.2 Packaging Options

【讨论】:

这对大多数人来说确实是解决这个问题的正确方法。【参考方案2】:

肯定会成功的

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

【讨论】:

不,它不会:这不包括许可证。根据上述许可条款,这是非法的。 不是即时编译项目的 tmp 解决方案 无论用途是什么,请阅读许可证:对于大多数人来说,您通过排除规则实现的目标是非法的。【参考方案3】:

如果您只有一个使用名称license.txt 的许可证(阅读:所有license.txt 副本都相同),则有一个解决方案:

packagingOptions 
   pickFirst  'META-INF/license.txt'

否则,Google 还发布了一个 Gradle 插件来管理依赖项许可证。见here。我没有尝试过,但它看起来能够聚合每个依赖项,甚至生成一个显示所有这些许可证的活动。

【讨论】:

我现在有 2 个许可证,一个来自 Apache 2.0,另一个来自 GPL 3.0。我目前的解决方法是在开发阶段排除它们,并在我们发布时手动包含它们。所有 license.txt 将被连接起来。与 notice.txt 相同无论如何,如果许可证相同,我喜欢您使用 pickFirst 的方法! 如果您能找到自动连接许可证的方法,我会全力以赴! 这是我现在正在调查的。首先我需要找出产生冲突的 gradle 任务是什么(以及如何)(为此我问了这个问题:***.com/questions/34287701/…)然后替换它 @Flowryn 你如何手动包含所有notice.txt,只需将它们复制到一个notice.txt 中?不能在jar文件中修改它 您提到问题出在正在使用的库中......在我的情况下,我负责创建我正在使用的库......我在制作时可能做错了什么他们?谢谢【参考方案4】:

我认为您只需要在 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'
    

【讨论】:

【参考方案5】:

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

那么你不应该在 android studio 中添加 firebase 库 IE。 文件->项目结构->云->firebase

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

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

【讨论】:

如果你使用jackson-databind,你添加一次就会出现问题。【参考方案6】:

将以下内容添加到相应的 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'
    

【讨论】:

这不包括对他们中的大多数人来说明确违反其条件的许可证。 这应该在当前 (2.*) 版本的 Gradle 的 android 闭包中【参考方案7】:

您可以在gradle中添加多个许可证see this

【讨论】:

以上是关于如何解决“在 APK META-INF/* 中复制的重复文件”的主要内容,如果未能解决你的问题,请参考以下文章

如何解决 Ajax 跨域请求不到的问题

如何解决包冲突问题

如何解决包冲突问题

如何解决ajax跨域问题

MySQL 的 10048问题,如何解决?

如何解决smartgit的冲突问题