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
中使用了packagingOptions
和exclude
,我也遇到了同样的问题。
你可以用这个来修复它。
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
。
【讨论】:
pickFirst
或 exclude
在运行发布版本时仍会输出警告。你能确认一下吗?
@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 条目)”的主要内容,如果未能解决你的问题,请参考以下文章