Proguard 警告“无法写入资源 [META-INF/MANIFEST.MF](重复的 zip 条目)”

Posted

技术标签:

【中文标题】Proguard 警告“无法写入资源 [META-INF/MANIFEST.MF](重复的 zip 条目)”【英文标题】:Proguard warnings "can't write resource [META-INF/MANIFEST.MF] (Duplicate zip entry)" 【发布时间】:2013-04-27 19:13:19 【问题描述】:

我正在使用 IntelliJ 并在调试模式下运行 Proguard,但我似乎无法摆脱以下警告:

ProGuard: [MyApplication] Warning: can't write resource [META-INF/MANIFEST.MF] 
(Duplicate zip entry [android-support-v13.jar:META-INF/MANIFEST.MF])

这个项目有几个模块,android-support-v13.jar 正在其中两个上使用。我认为这是问题所在,所以我从 libs 文件夹中删除了该库,将其添加为项目库并将依赖项添加到两个模块中。那没有解决任何问题,警告仍然存在,我不明白为什么。

我知道这些警告不会影响任何事情,但干净的构建是一个快乐的构建!

【问题讨论】:

看起来android-support-v13.jar 被包含了不止一次。另请参阅Warning: can't write resource ... Duplicate zip entry。 我不明白这是怎么回事。就像我说的,我将该库添加为项目库并在两个模块上引用它。我需要这样做,否则应用程序将无法编译。 可能是“proguard.cfg”问题。你能发一下吗?好像里面包含的一些-injars可以被处理两次。 尝试删除 c:/ProgramFiles/User/.gradle 文件夹 【参考方案1】:

可能是“proguard.cfg”问题。它是否包括任何“-injars”?如果您的项目包含另一个项目作为库,则可以处理两次 jar。你能发布你的“proguard.cfg”吗?

从http://proguard.sourceforge.net/index.html#manual/troubleshooting.html中提取:

您的输入 jar 包含多个同名的资源文件。 ProGuard 像往常一样继续复制资源文件,跳过任何 以前使用过的名称的文件。再一次,警告可能是 虽然有一些问题的迹象,所以建议删除 重复。一种方便的方法是在 输入罐子。没有关闭这些警告的选项。

选项 #1:

由于您无法发布“-injars”,请检查它们是否包含“android-support-v13.jar”或项目中包含的库,该库本身也包含“android-support-v13.jar”。

假设您在 IntelliJ IDEA 中使用 Ant 构建,您不能添加 -injars、-outjars 或 -libraryjars 选项; Ant 脚本已经为您做到了。

选项 #2:

虽然警告是无害的,但干净的构建是一个快乐的构建,所以试试吧:

http://web.archive.org/web/20160206204259/http://www.dancartoon.com/2012/01/14/fixing-proguard-warning-cant-write-resource-meta-infmanifest-mf/

https://gist.github.com/paulpv/4439012

选项 #3:

在每个“-injars”命令之后包含(!META-INF/MANIFEST.MF)

-injars library.jar(!META-INF/MANIFEST.MF)

选项 #4: Android Proguard Duplicate Definition

通过将第 3 方库移动到另一个目录来解决此问题,在 我的案例'lib'。然后加了

-injars lib/jmdns.jar 

到 proguard.cfg 文件。

选项 #5: Android - Proguard duplicate zip entry error

如果您的 Proguard 配置文件包含以下行,请将其删除:

-injars bin/classes

选项 #6: Android obfuscate app using proguard keeps obfuscating library jars - or is it?

我发现了另一种让 Proguard 单独离开库 jar 的方法是 要求它保留他们的包名,例如:

-保持类 javax.** *; -keep class org.** *; -keep class twitter4j.** *;

选项 #7:

一个奇怪的解决方案(删除 src 文件夹中的 META-INF 文件夹)类似于here。

【讨论】:

是的,它确实包含一个带有-injars 的部分。我无法发布该文件,它包含我无法透露的敏感数据。 android-support-v13.jar 只是一个示例,主模块的 libs 文件夹中的所有其他库也生成了该警告。 尝试从 -injars 中删除这些库 好吧,我用替代解决方案更新了我的答案。没有你的配置文件和完整的错误日志很难。 我似乎无法摆脱这个,可能是因为这个项目配置有问题。我现在只能这样了。但是由于您提供了如此详细的答案以及许多可能的解决方案,因此我会将答案标记为已接受。谢谢你的时间:)【参考方案2】:

我在build.gradle 中使用了packagingOptionsexclude,我也遇到了同样的问题。

你可以用这个来修复它。

packagingOptions  
    pickFirst 'META-INF/services/javax.annotation.processing.Processor'
    pickFirst 'META-INF/DEPENDENCIES.txt'
    pickFirst 'META-INF/DEPENDENCIES'
    pickFirst 'META-INF/LICENSE.txt'
    pickFirst 'META-INF/LICENSE'
    pickFirst 'META-INF/NOTICE.txt'
    pickFirst 'META-INF/NOTICE'
    pickFirst 'META-INF/LGPL2.1'

pickFirst 替换为exclude

【讨论】:

pickFirstexclude 在运行发布版本时仍会输出警告。你能确认一下吗? @JJD 它仍然输出警告。 pickFirst 不会阻止警告的发生。【参考方案3】:

我找到的最佳解决方案是将 -obfuscate 目标从 /tools/ant/build.xml 复制到项目的 custom_rules.xml 中。那么唯一需要更改的块是:

<pathconvert property="project.all.classes.value" refid="project.all.classes.path">
    <firstmatchmapper>
         <regexpmapper from='^([^ ]*)( .*)$$' to='"\1\2"(!META-INF/MANIFEST.MF)'/>
         <identitymapper/>
    </firstmatchmapper>
</pathconvert>

唯一添加的位是(!META-INF/MANIFEST.MF)。这将排除所有清单文件,这些文件无论如何都不会复制到最终的 APK 中。

【讨论】:

【参考方案4】:

不要通过直接包含其 jar 来引用支持库;当你这样做时,构建系统无法在它的多个版本之间消除歧义,并且你会得到这种类型的错误。通过引用它的 Maven 坐标来包含它:

依赖 编译'com.android.support:support-v13:X.X.X' 其中 X.X.X 是基于您正在编译的 API 的正确版本号。如果您通过 UI 在 Project Structure > (your module) > Dependencies > + Button > Library 依赖项中包含此依赖项,它将帮助您选择正确的版本号。

您可能还会发现通过 Maven 坐标包含其他依赖项而不是争吵它们的 jar 包很方便;同一个库依赖 UI 具有搜索功能,可帮助您查找库。

请务必从 libs 或它所在的任何其他文件夹中删除此库

【讨论】:

【参考方案5】:

-dontwarn 添加到proguard.cfg 以忽略警告

【讨论】:

这不是一个好的选择,因为无论如何您都只是忽略所有警告。其中一些实际上可能对您有所帮助!

以上是关于Proguard 警告“无法写入资源 [META-INF/MANIFEST.MF](重复的 zip 条目)”的主要内容,如果未能解决你的问题,请参考以下文章

收到太多 Proguard 警告

使用 Proguard 进行改造警告

如何抑制来自 ProGuard 的“也许这是程序方法”警告

Proguard 警告:找不到引用的类 scala。*

Android Roboguice proguard 警告

Proguard 告诉我“请先更正上述警告。”。如何解决外部 jar 的引用?