转自:http://www.dancartoon.com/2012/01/14/fixing-proguard-warning-cant-write-resource-meta-infmanifest-mf/转自:

We're using ProGuard in our Android build and were getting a number of warnings regarding duplicate entries in the output jar. When ProGuard encounters resources in an input jar, it will by default copy the resources into the output jar. This is fine as long as you don't have multiple jars that contain resources with the same name. All jars(that I'm aware of) have manifest files, so attempting to use ProGuard with multiple input jars will cause warnings that look like: "Warning: can't write resource [META-INF/MANIFEST.MF] (Duplicate zip entry [yyy.jar:META-INF/MANIFEST.MF])".

The warnings are harmless, but a clean build is a happy build, so we might as well try and get rid of them. The ProGuard Manual actually describes what needs to be done, but it only provides a solution for the case where input jars are specified individually:

123
         
-injars in1.jar
-injars in2.jar(!META-INF/MANIFEST.MF)
-injars in3.jar(!META-INF/MANIFEST.MF)
view raw gistfile1.txt hosted with ❤ by  GitHub

When using ProGuard in the Android build process, the default behavior is to pass in all input jars in a giant delimited(semi-colon on Windows) blob. I have done some experimentation, but was unable to determine how an input filter can be used when multiple jars(having absolute paths) are passed in this way. Fortunately, it's not too difficult to change the build process to pass in a list of input jars individually and with individual filters.

This is the relevant section of the standard Android build.xml(starting around line 700):

123456789101112131415161718192021222324252627282930313233
         
<!-- Build a path object with all the jar files that must be obfuscated.
This include the project compiled source code and any 3rd party jar
files. -->
<path id="project.jars.ref">
<pathelement location="${preobfuscate.jar.file}" />
<path refid="jar.libs.ref" />
</path>
<!-- Set the project jar files Path object into a single property. It'll be
all the jar files separated by a platform path-separator.
Each path must be quoted if it contains spaces.
-->
<pathconvert property="project.jars" refid="project.jars.ref">
<firstmatchmapper>
<regexpmapper from='^([^ ]*)( .*)$$' to='"\1\2"'/>
<identitymapper/>
</firstmatchmapper>
</pathconvert>
<mkdir dir="${obfuscate.absolute.dir}" />
<delete file="${preobfuscate.jar.file}"/>
<delete file="${obfuscated.jar.file}"/>
<jar basedir="${out.classes.absolute.dir}"
destfile="${preobfuscate.jar.file}" />
<proguard>
@${proguard.config}
-injars ${project.jars}
-outjars "${obfuscated.jar.file}"
-libraryjars ${android.libraryjars}
-dump "${obfuscate.absolute.dir}/dump.txt"
-printseeds "${obfuscate.absolute.dir}/seeds.txt"
-printusage "${obfuscate.absolute.dir}/usage.txt"
-printmapping "${obfuscate.absolute.dir}/mapping.txt"
</proguard>
view raw gistfile1.xml hosted with ❤ by  GitHub

The directives above create a new object that combines the location of the compiled jar along with other jars that were used during compilation. These locations are then joined into a string by the pathconvert task, which also does some transformation to ensure that paths containing spaces are quoted properly. Finally, the string from pathconvert(stored in project.jars) is passed into proguard via the statement: "-injars ${project.jars}"

Update(2013/02/11): paulpv has provided an updated config since the Android build system has changed since my original post. I have included his config here:

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
         
<?xml version="1.0" encoding="UTF-8"?>
<project name="custom_rules">
<!--
Suppress "Warning: can't write resource [META-INF/MANIFEST.MF] (Duplicate zip entry [classes.jar:META-INF/MANIFEST.MF])".
Per http://www.dancartoon.com/2012/01/14/fixing-proguard-warning-cant-write-resource-meta-infmanifest-mf/
Target "-obfuscate" copied from ${sdk.dir}/tools/ant/build.xml v21.
-->
<target name="-obfuscate">
<if condition="${proguard.enabled}">
<then>
<property name="obfuscate.absolute.dir" location="${out.absolute.dir}/proguard" />
<property name="preobfuscate.jar.file" value="${obfuscate.absolute.dir}/original.jar" />
<property name="obfuscated.jar.file" value="${obfuscate.absolute.dir}/obfuscated.jar" />
<!-- input for dex will be proguard's output -->
<property name="out.dex.input.absolute.dir" value="${obfuscated.jar.file}" />
<!-- Add Proguard Tasks -->
<property name="proguard.jar" location="${android.tools.dir}/proguard/lib/proguard.jar" />
<taskdef name="proguard" classname="proguard.ant.ProGuardTask" classpath="${proguard.jar}" />
<!-- Set the android classpath Path object into a single property. It'll be
all the jar files separated by a platform path-separator.
Each path must be quoted if it contains spaces.
-->
<pathconvert property="project.target.classpath.value" refid="project.target.class.path">
<firstmatchmapper>
<regexpmapper from='^([^ ]*)( .*)$$' to='"\1\2"'/>
<identitymapper/>
</firstmatchmapper>
</pathconvert>
<!-- Build a path object with all the jar files that must be obfuscated.
This include the project compiled source code and any 3rd party jar
files. -->
<path id="project.all.classes.path">
<pathelement location="${preobfuscate.jar.file}" />
<path refid="project.all.jars.path" />
</path>
<!-- Set the project jar files Path object into a single property. It'll be
all the jar files separated by a platform path-separator.
Each path must be quoted if it contains spaces.
-->
<!--
Old:
<pathconvert property="project.all.classes.value" refid="project.all.classes.path">
New:
-->
<pathconvert property="project.all.classes.value" refid="project.all.jars.path" pathsep=" ">
<firstmatchmapper>
<!--
Old:
<regexpmapper from='^([^ ]*)( .*)$$' to='"\1\2"'/>
<identitymapper/>
New:
-->
<regexpmapper from='^([^ ]*)( .*)$$' to='-injars "\1\2"(!META-INF/MANIFEST.MF)'/>
<regexpmapper from='(.*)' to='-injars \1(!META-INF/MANIFEST.MF)'/>
</firstmatchmapper>
</pathconvert>
<!-- Turn the path property ${proguard.config} from an A:B:C property
into a series of includes: -include A -include B -include C
suitable for processing by the ProGuard task. Note - this does
not include the leading '-include "' or the closing '"'; those
are added under the <proguard> call below.
-->
<path id="proguard.configpath">
<pathelement path="${proguard.config}"/>
</path>
<pathconvert pathsep='" -include "' property="proguard.configcmd" refid="proguard.configpath"/>
<echo>proguard: $${project.all.classes.value}=${project.all.classes.value}</echo>
<mkdir dir="${obfuscate.absolute.dir}" />
<delete file="${preobfuscate.jar.file}"/>
<delete file="${obfuscated.jar.file}"/>
<jar basedir="${out.classes.absolute.dir}"
destfile="${preobfuscate.jar.file}" />
<proguard>
-include "${proguard.configcmd}"
-include "${out.absolute.dir}/proguard.txt"
-injars ${preobfuscate.jar.file}
${project.all.classes.value}
-outjars "${obfuscated.jar.file}"
-libraryjars ${project.target.classpath.value}
-dump "${obfuscate.absolute.dir}/dump.txt"
-printseeds "${obfuscate.absolute.dir}/seeds.txt"
-printusage "${obfuscate.absolute.dir}/usage.txt"
-printmapping "${obfuscate.absolute.dir}/mapping.txt"
</proguard>
</then>
</if>
</target>
</project>
view raw custom_rules.xml hosted with ❤ by  GitHub

The goal of my changes is to preserve the manifest files from the original jar("preobfuscate.jar.file") and ignore(filter) the manifest files from the remaining input jar files. Since I haven't figured out how to filter input jars when passed in as a blob, I instead use the pathconvert task to transform each input jar location into a separate "-injars" statement with its own manifest filter. The property containing these locations is then passed into ProGuard directly via: "${project.jars}"

The solution isn't as clean as I would have liked, but it does fix the warnings.

Warning: can't write resource [META-INF/MANIFEST.MF] (Duplicate zip entry [yyy.jar:META-INF/MANIFEST相关推荐

  1. java jar manifest文件,java打包jar,以及manifest文件使用说明

    java打包jar,以及manifest文件使用说明 http://20921556.javaeye.com/blog/263974 关键字: java jar Java的一种文档格式,JAR文件非常 ...

  2. java原生和SpringBoot读取jar包中MANIFEST.MF的方式

    我们经常看到java的一些jar包META-INF目录下包含一个MANIFEST.MF文件,里面包含一些版本信息,标题,实现组织,很多第三方的jar包还会自定义一个属性. 本文讲解如何读取jar包中M ...

  3. Maven打包自定义MANIFEST.MF键值对

    编写java后,一般都是通过打包生成jar.war包提供使用,一般在打包后都会在jar包中生成MANIFEST.MF文件 编写一个简单的java文件. package cn.kanyun;public ...

  4. meta-inf文件夹以及MANIFEST.MF文件的作用

    meta-inf相当于一个信息包,目录中的文件和目录获得Java 2平台的认可与解释,用来配置应用程序.扩展程序.类加载器和服务 manifest.mf文件,在用jar打包时自动生成的. META-I ...

  5. MANIFEST.MF属性读写

    本案例完整演示项目 https://download.csdn.net/download/cs4380/10835284 一.maven打包写入MANIFEST.MF属性 本案例采用maven写入,可 ...

  6. META-INF/MANIFEST.MF介绍

    META-INF文件夹相当于一个信息包,目录中的文件和目录获得Java 2平台的认可与解释,用来配置应用程序.扩展程序.类加载器和服务.这个文件夹和其中的 MANIFEST.MF文件,在用jar打包时 ...

  7. META-INF/MANIFEST.MF介绍 _

    原文地址:https://www.cnblogs.com/jayworld/p/9767228.html META-INF文件夹相当于一个信息包,目录中的文件和目录获得Java 2平台的认可与解释,用 ...

  8. Idea打包jar,MANIFEST.MF文件没有Main-Class属性 xxx.jar中没有主清单属性

    Idea打包jar 下图中圈出来的路径不能是默认的,需要放在项目根路径下,修改为:D:\IntelliJIdea\project\MyFtpServer\META-INF\MANIFEST.MF. 修 ...

  9. MANIFEST.MF文件的格式

    MANIFEST.MF文件的格式 1. 基本格式 属性名称+:+空格+属性值 2. 没行最多72个字符,换行继续必须以空格开头 3. 文件最后必须要有一个回车换行 4. Class-Path 当前路径 ...

最新文章

  1. 告别CNN?一张图等于16x16个字,计算机视觉也用上Transformer了
  2. Struts 验证码登陆
  3. 时尚的基因是创新 -- 旺旺平台产品线员工大会即兴发言提要
  4. 未来5年,中国会有多少企业营收能达到1000亿美元以上?
  5. 190520每日一句
  6. SaaSpace:12种最好的免费甘特图软件工具
  7. 文件共享锁溢出 请增加MaxLocksperFile注册表项值
  8. LocalDateTime生成当天、当月起止时间的时间戳
  9. DirectX 教程: DirectX Tutorial - Direct3D: Getting Started
  10. android 内部 存储空间不足,安卓手机内存空间不足的解决方法
  11. Kibana使用(Discover):数据的查询
  12. 经验丰富的视觉设计师自我介绍怎么写
  13. 什么是三态输出电路?什么是集电极开路输出和漏极开路输出?
  14. ncurses库的安装与入门
  15. 20221215今天的世界发生了什么
  16. python三维矩阵出图_python读取图片的方式,以及将图片以三维数组的形式输出方法...
  17. 乐视屏霸android版本,乐视屏霸安装第三方应用看电视直播、点播教程
  18. ORCID和ORCID iD是什么?
  19. 信息系统项目管理师第四版知识摘编:第2章 信息技术发展
  20. [免费赠送] 四本有关linq 的英文原版电子书

热门文章

  1. SLF4J 使用详细
  2. 白杨SEO:公众号为什么会增加视频/视频号和服务?公众号视频号如何互相绑定?视频号公众号又如何互相解绑?启发是什么?
  3. 学校计算机校本培训工作总结,小学信息技术校本培训工作总结.doc
  4. java图片上传_JavaWeb实现上传图片
  5. 关于java多态,向上转型,向下转型
  6. 神奇的迁移工具 migrate 小计
  7. 计算机网络基础知识点学习(一)(概述)
  8. 曾刷新两项世界纪录,腾讯优图人脸检测算法 DSFD 正式开源...
  9. Github上最好用的Android状态栏导航栏库
  10. ConstraintTools...