Jar
该 Task 的作用是将一组文件打包成 jar 包。basedir
attribute 所引用的目录就是进行打 jar 包的目录。请注意,文件权限不会存储在结果文件中。
可以通过 includes
、includesfile
、excludes
、excludesfile
和 defaultexcludes
这些 attribute 来选择文件集合中哪些文件会被打包到目标 jar 包中。includes
或 includesfile
attribute 用于指定打包时需要包含的文件。exclude
或 excludesfile
attribute 用于指定打包时需要排除的文件,这也是通过模式匹配来实现的。最后,使用 defaultexcludes
可以指定是否要使用默认排除。请参阅关于基于目录的 Task 、包含/排除文件的工作方式以及如何编写模式的部分内容。
此 Task 形成一个隐式的 FileSet 数据类型,并支持
(dir 变为 basedir)的大多数 attribute 以及
嵌套的
、
和
元素。还可以使用嵌套文件集来获得更大的灵活性,并指定多个文件集来将不同的文件树合并到一个 jar 中。zip
Task 中扩展的 fileset
和 groupfileset
子元素也可以在 jar
Task 中使用。有关更多详细信息和示例,请参见 zip
Task 文档。
update
参数控制着当目标 jar 文件已经存在时会发生什么。当设置为 yes
时,jar 文件将用指定的文件进行更新。当设置为 no
(默认值)时,jar 文件将被覆盖。zip
Task 文档中提供了一个示例。请注意,zip 文件以 2 秒的间隔存储文件的修改时间。如果文件的修改时间晚于归档中对应文件的修改时间不到 2 秒,Ant 将认为它不需要更新。
如果省略 manifest
(清单)attribute,Apache Ant 将提供一个简单的清单。whenmanifestonly
参数控制当没有匹配文件时(除了清单文件或嵌套服务之外)的行为。如果该参数设置为 skip
,则不会创建 jar 并发出警告。如果该参数设置为 fail
,则不会创建 jar,构建将因错误而暂停。如果是 create
(默认),则创建一个空 jar 文件(仅包含清单和服务)。
jar
Task 有一个指定 jar 包中清单文件的快捷方式。同样的事情也可以通过在 zip
Task 中使用 zipfileset
子元素的 fullpath
attribute 来实现。一个区别是,如果没有指定 manifest
attribute,jar
Task 将为您包含一个空的清单文件。清单由 jar
Task 根据 jar 文件规范进行处理。特别注意,这可能会导致大于 72 字节的行被换行到下一行显示。jar
Task 检查您是否根据版本规范指定了包信息。
请注意,zip格式允许同一个归档文件中存在多个相同完全限定名的文件。如果要避免此行为,必须将 duplicate
attribute 设置为默认值(add
)以外的值 。
要对 jar 文件进行加密签名,请在此任务中创建的 jar 上使用 Signjar Task 。
对于创建 JEP 238 multi-release 的 jar 文件,您不需要任何特殊工具。只需设置所需的 manifest 条目并将文件放置在所需的位置,如下面的 JEP 238 示例所示。如果你想调整这种 jar,例如通过从 versions 分支中删除 same
类来减小大小,你必须做更多。
参数
Attribute | 描述 | 必需 |
---|---|---|
destfile | 要创建的 jar 文件名。 | Yes |
basedir | 要打成 jar 包的基础目录,即该目录下的文件将打成 jar 包。 | No |
compress | 不仅存储数据,还压缩数据。除非将 keepcompression attribute 设置为 false ,否则这将应用于整个存档,而不仅仅是更新时添加的文件。 |
No; 默认为 true |
keepcompression | 对于来自现有归档文件的条目(如嵌套 zipfilesets 或更新归档文件时),保持压缩原样,而不是使用 compress attribute。从 Ant 1.6 开始。 |
No; 默认为 false |
encoding | 用于存档中文件名的字符编码。不建议更改此值,否则创建的归档文件很可能无法用于 Java。另请参见 zipTask 页面中的讨论。 | No; 默认为 UTF8 |
filesonly | 仅保存文件条目。 | No; 默认为 false |
includes | 需要包含的文件 pattern 列表,列表中的各 pattern 之间使用逗号或空格分隔。 | No; 默认为全部 (**) |
includesfile | 一个文件名。该文件中的每一行将被当做一个需要包含的文件 pattern。 | No |
excludes | 需要排除的文件 pattern 列表,列表中的各 pattern 之间使用逗号或空格分隔。 | No; 默认为 defaultexcludes attribue 的值,如果defaultexcludes 为 no 的话,则为 none |
excludesfile | 一个文件名。改文件中的每一行将被当做一个需要排除的文件 pattern。 | No |
defaultexcludes | 表明是否使用默认的排除。值可为 yes 或 no 。 |
No; 默认为 yes |
manifest | 指定所用的清单。可以是一个清单文件的位置,或者是通过 fileset 添加的一个 jar 文件的名称。如果是一个 jar 文件的名称,该 Task 将使用该 jar 文件中的清单文件:META-INF/MANIFEST.MF 。 |
No |
filesetmanifest | 指定当在 zipfileset 或 zipgroupfileset 中发现一个清单文件时的行为。可用的值有 skip 、merge 和 mergewithoutmain 。merge 会将所有清单合并在一起,并将其放入其他指定的清单中。mergewithoutmain 将合并除清单主 section 以外的所有内容。 |
No; 默认为 skip |
update | 如果目标文件已存在,指示是否更新或覆盖目标文件。 | No; 默认为 false |
whenmanifestonly | 指定当没有文件匹配时的行为。有效值为 fail 、skip 和 create 。 |
No; 默认为 create |
duplicate | 指定当发现重复文件时的行为。有效值为 add 、preserve 和 fail 。 |
No; 默认为 add |
index | 是否创建索引列表以加快类加载。除非使用嵌套的 indexjars 元素指定其他 jar,否则索引中将只包含此 jar 的内容。 | No; 默认为 false |
indexMetaInf | 是否在索引中包含 META-INF 及其子文件。如果 index 参数为 false ,则该参数没有任何效果。Sun 的 jar 实现曾经跳过 META-INF 目录,Ant 也遵循了这个惯例。Java 5 改变了这种行为。为了避免 Java 1.4 或更早版本上 Ant 生成的 jar 出现问题,除非明确要求,否则 Ant 不会包含 META-INF。自 Ant 1.8.0 以来引入该参数。 |
No; 默认为 false |
manifestencoding | 当通过 manifest 参数指定了清单文件时,该参数用于读取 jar 清单的编码。在编写清单时,该 Task 将始终使用 UTF-8。 |
No; 默认为默认 JVM 的字符编码 |
roundup | 是否将文件修改时间四舍五入到下一个偶数秒。zip 归档文件时以 2 秒的粒度存储文件修改时间,因此时间将向上或向下取整。如果向下取整,则当您重新运行 Task 时,归档文件将始终看起来过时,因此默认为向上取整。四舍五入可能会导致不同类型的问题,如 web 归档文件中的 JSP,这些问题似乎比预编译页面更为新,从而导致预编译无效。从 Ant 1.6.2 开始引入该参数。 | No; 默认为 true |
level | 指定执行文件压缩的级别。有效值范围从 0(无压缩/最快)到 9(最大压缩/最慢)。从 Ant 1.7 开始引入该参数。 | No |
strict | 配置如何处理打包版本规范的中断:fail :抛出 BuildException,warn :在 warn 级别记录消息,ignore :在 verbose 级别记录消息(默认)。自 Ant 1.7.1 开始引入该参数。 |
No; 默认为 ignore |
preserve0permissions | 在更新存档文件或添加来自其他存档文件的条目时,Ant 将假定 Unix 权限值为0(不允许任何人对文件/目录执行任何操作),这意味着权限根本没有被存储,而不是真正的权限,而是将应用其自己的默认值。如果确实要保留原始权限,请将此属性设置为 true。自 Ant 1.8.0 开始引入该参数。 | No; 默认为 false |
useLanguageEncodingFlag | 如果编码是 UTF-8,是否设置语言编码标志(flag)。如果编码不是 UTF-8,此设置没有任何效果。自 Ant 1.8.0 开始引入该参数。另请参见 zipTask 页面中的讨论。 | No; 默认为 true |
createUnicodeExtraFields | 是否创建 Unicode 额外字段以在条目的元数据中再次存储文件名。可能的值 never 、always 和 not-encodeable ,这将仅在文件名无法编码时添加 Unicode 额外字段。另请参见 zipTask 页面中的讨论。 |
No; 默认为 never |
fallbacktoUTF8 | 如果无法使用指定的编码对文件名进行编码,是否使用 UTF-8 和语言编码标志而不是指定的编码。从 Ant1.8.0 开始引入该参数。另请参见 zipTask 页面中的讨论。 | No; 默认为 false |
mergeClassPathAttributes | 是否合并在不同清单中找到的 Class-Path attribute(如果合并清单)。如果为 false,则仅保留上次合并的清单的 attribute 。从 Ant 1.8.0 开始引入该参数。除非您还将 flattenAttributes 设置为 true,否则这可能会导致清单包含多个违反清单规范的 Class-Path attribute。 |
No; 默认为 false |
flattenAttributes | 是否将 section 中多次出现的 attribute(这只能发生在 Class-Path attribute 中)合并到单个 attribute 中。从 Ant 1.8.0 开始引入该参数。 |
No; 默认为 false |
zip64Mode | 何时对条目使用 Zip64 扩展名。可能的值有 never 、always 和 as-needed 。从 Ant 1.9.1 开始引入该参数。另请参见 zipTask 页面中的讨论。 |
No; 默认为 never |
指定为嵌套元素的参数
metainf
。嵌套的 metainf 元素指定一个 FileSet。该文件集中包含的所有文件最终将位于 jar 文件的 META-INF 目录中。如果该文件集包含名为MANIFEST.MF
的文件时,该文件被忽略,您将得到一个警告。manifest
。嵌套的manifest
元素允许在构建文件中(而不是在外部文件中)内联提供 jar 文件的清单。此元素与 manifest Task 相同,但必须省略file
和mode
attribute。如果同时指定了内联清单和外部文件,则合并清单。当使用内联清单时,jar Task 将检查清单内容是否已更改,即指定的清单与存在于jar 中的清单(如果它存在的话)有任何不同。如果清单值发生了更改,则将根据需要更新或重新构建 jar。-
indexjars
。从 Ant 1.6.2 开始引入该参数,嵌套的indexjars
元素指定了一个 path-like 的结构。除非将 jar Task 的index
attribute 设置为 true,否则它的内容将完全被忽略。该 Task 创建的索引将包含该路径中归档文件的索引,归档文件的名称取决于你的清单:- 如果生成的 jar 文件的清单不包含
Class-Path
attribute,将使用没有任何前置目录的文件名,且该路径的所有部分都将会建立索引。 - 如果清单包含
Class-Path
attribute,该 Task 将尝试猜测Class-Path
的哪一部分属于给定的归档文件。如果无法猜出名称,则跳过归档,否则将使用Class-Path
attribute 中列出的名称。
除非将
indexmetainf
attribute 设置为 true,否则该 Task 将不会为空归档、或只包含 META-INF 目录中的文件的归档创建任何索引项。 - 如果生成的 jar 文件的清单不包含
indexjarsmapper
。自 Ant 1.10.9 开始引入该参数。嵌套的indexjarsmapper
元素可以用于执行由indexjars
指定的归档文件的自定义文件名转换(如果默认的文件名转换不能满足要求的话)。-
service
。自 Ant 1.7.0 开始引入该参数。嵌套的service
元素指定了一个服务。服务在服务提供者概述中有描述。方法就是在提供商者 jar 文件中包含由所提供的服务命名的文件,例如 META-INF/services/javax.script。ScriptEngineFactory 可以包含实现类名,每行一个(通常每个 jar 一行 )。服务的名称由type
attribute 设置。实现服务的类名是provider
attribute,或者如果想指定一批实现服务的类,则通过provider
嵌套元素。Attribute 描述 必须 type 服务的名称。 Yes provider 服务实现类的类名。 Yes, 除非有一个内嵌的
元素。提供者指定的类名可以由
provider
attribute 指定,也可以由嵌套的
元素指定,该元素只有一个classname
attribute。如果一个 jar 文件中有多个服务实现,可能会使用多个嵌套的
元素。
示例
简单示例
将 ${build}/classes
目录下的所有文件jar到 ${dist}/lib
目录下的 app.jar 文件中。
使用过滤器
将 ${build}/classes
目录下的所有文件打包到 ${dist}/lib
目录下的 app.jar 文件中。名称为 Test.class 的文件将被排除。
将 ${build}/classes
目录下的所有文件打包到 ${dist}/lib
目录下的 app.jar 文件中。只使用目录 mypackage/test 下的文件,并排除名为 Test.class 的文件。
多文件集
将 ${build}/classes
目录下的所有文件和 ${src}/resources
目录下的所有文件一起放到 ${dist}/lib
目录下的 app.jar 文件中。名称为 Test.class 的文件将被排除。如果有像 ${build}/classes/mypackage/MyClass.class
和 ${src}/resources/mypackage/image.gif
这样的文件,它们将出现在 jar 中的相同目录中(因此被 Java 认为是在同一个包中)。
合并归档
用主类 com.acme.checksites.Main
创建一个可执行 jar 文件,然后嵌入 lib/main/some.jar 中的所有类。
用主类 com.acme.checksites.Main
创建一个可执行 jar 文件,还有 lib/main 目录下所有 jar 文件中的所有类。
内联清单(Inline manifest)
这是包含构建程序(Implementation-Version
)版本的内联清单规范的一个示例。注意,Built-By
attribute 将接受 Ant property user.name
的值。上面生成的清单如下所示:
Manifest-Version: 1.0
Permissions: sandbox
Codebase: example.com
Built-By: conor
Implementation-Vendor: ACME inc.
Implementation-Title: GreatProduct
Implementation-Version: 1.0.0beta2
Created-By: Apache Ant 1.9.2
Name: common/MyClass.class
Sealed: false
Service Provider
下面展示了如何创建一个 jar 文件,指定一个具有脚本接口实现的服务:
下面演示如何创建一个 jar 文件,指定一个具有脚本接口的两个实现的服务:
JEP 238 示例
在这里,我们希望根据规范 JEP 238 创建一个 Multi-Release jar File。它在 jar 之上定义了在 jar 中放置额外的类或覆盖类的可能性,这些类根据您运行的 Java 版本而可用。也就是说,必须设置清单条目 Multi-Release: true
,把所有额外的类或覆盖的类放在 META-INF/versions/number/package-structure
,例如 META-INF/versions/9/org/apache/ant/MyClass.class
。在这个示例中,我们希望将一般类编译成 ${java.classes}
,而将 Java 9 的类被编译为 ${java9.classes}
。
War
jar
Task 的一个扩展,对应该在 WEB 应用程序归档(war 包)的 WEB-INF/lib
、WEB-INF/classes
或 WEB-INF
目录中的文件进行了特殊处理。war
Task 是指定 War 文件特定布局的快捷方式。在 zip
或 jar
Task 中使用 zipfilesets
的 prefix
和 fullpath
attribute 也可以实现同样的功能。zip
Task 中的扩展 zipfileset
元素(具有 prefix
、fullpath
和 src
attribute)在 war
Task 中可用。该 Task 还启用了资源,并将向存档中添加嵌套资源和资源集合。
在 Servlet API 2.5/Java EE 5 之前,war 文件中必须包含 WEB-INF/WEB.xml
文件,因此如果缺少 webxml
attribute,则此 Task 将失败。由于 web.xml 文件现在是可选的,因此 webxml
attribute 现在可以成为可选的。但是,由于大多数真实的 WEB 应用程序确实需要 web.xml 文件,因此默认情况下它不是可选的。如果不包括该文件,则任务将失败,除非 needxmlfile
attribute 设置为 false。如果通过文件集向 jar 添加了多个 web.xml 文件,则该 Task 将发出警告。
请注意,zip 格式允许在单个存档中存在多个具有相同完全限定名称的文件。这会对毫无戒心的用户造成各种问题。如果要避免此行为,必须将 duplicate
attribute 设置为默认值(add
)之外的值。
参数
Attribute | Description | Required |
---|---|---|
destfile | 要创建的 war 文件路径。 | Yes |
webxml | 所用的 Servlet 配置描述(WEB-INF/web.xml)。 | Yes。除非 needxmlfile attribute 为 true,web.xml 将通过嵌套文件集拉入,或在现有 War 文件更新时拉入。 |
needxmlfile | 是否需要 web.xml 文件的标记。当生成 Servlet 2.5+ 的 War 文件(可以没有 web.xml 文件)时,该 attribute 可以设置为 false。自 Ant 1.7 开始引入该 attribute。 | No;默认为 true |
basedir | 要打包的基础目录,即该目录下的文件将打成 WAR 包。 | No |
compress | 不仅存储数据,还压缩数据。除非将 keepcompression attribute 设置为 false ,否则这将应用于整个存档,而不仅仅是更新时添加的文件。 |
No;默认为 true |
keepcompression | 对于来自现有归档文件的条目(如嵌套 zipfilesets 或更新归档文件时),保持压缩原样,而不是使用 compress 属性。从 Ant 1.6 开始。 |
No;默认为 false |
encoding | 用于存档中文件名的字符编码。不建议更改此值,否则创建的归档文件很可能无法用于 Java。另请参见 zipTask 页面中的讨论。 | No; 默认为 UTF8 |
filesonly | 仅保存文件条目。 | No;默认为 false |
includes | 需要包含的文件 pattern 列表,列表中的各 pattern 之间使用逗号或空格分隔。 | No; 默认为全部 (**) |
includesfile | 一个文件名。该文件中的每一行将被当做一个需要包含的文件 pattern。 | No |
excludes | 需要排除的文件 pattern 列表,列表中的各 pattern 之间使用逗号或空格分隔。 | No; 默认为 defaultexcludes attribue 的值,如果defaultexcludes 为 no 的话,则为 none |
excludesfile | 一个文件名。改文件中的每一行将被当做一个需要排除的文件 pattern。 | No |
defaultexcludes | 表明是否使用默认的排除。值可为 yes 或 no 。 |
No; 默认为 yes |
manifest | 指定所用的清单。 | No |
filesetmanifest | 指定当在 zipfileset 或 zipgroupfileset 中发现一个清单文件时的行为。可用的值有 skip 、merge 和 mergewithoutmain 。merge 会将所有清单合并在一起,并将其放入其他指定的清单中。mergewithoutmain 将合并除清单主 section 以外的所有内容。 |
No; 默认为 skip |
whenmanifestonly | 指定当没有文件匹配时的行为。有效值为 fail 、skip 和 create 。 |
No;默认为 create |
update | 如果目标文件已存在,指示是否更新或覆盖目标文件。 | No; 默认为 false |
duplicate | 指定当发现重复文件时的行为。有效值为 add 、preserve 和 fail 。 |
No;默认为 add |
roundup | 是否将文件修改时间四舍五入到下一个偶数秒。zip归档文件时以 2 秒的粒度存储文件修改时间,因此时间将向上或向下取整。如果向下取整,则当您重新运行 Task 时,归档文件将始终看起来过时,因此默认为向上取整。四舍五入可能会导致不同类型的问题,如 web 归档文件中的 JSP,这些问题似乎比预编译页面更为新,从而导致预编译无效。从 Ant 1.6.2 开始引入该参数。 | No;默认为 true |
level | 指定执行文件压缩的级别。有效值范围从 0(无压缩/最快)到 9(最大压缩/最慢)。从 Ant 1.7 开始引入该参数。 | No |
preserve0permissions | 在更新存档文件或添加来自其他存档文件的条目时,Ant 将假定 Unix 权限值为0(不允许任何人对文件/目录执行任何操作),这意味着权限根本没有被存储,而不是真正的权限,而是将应用其自己的默认值。如果确实要保留原始权限,请将此属性设置为 true。自 Ant 1.8.0 开始引入该参数。 | No; 默认为 false |
useLanguageEncodingFlag | 如果编码是 UTF-8,是否设置语言编码标志(flag)。如果编码不是 UTF-8,此设置没有任何效果。自 Ant 1.8.0 开始引入该参数。另请参见 zipTask 页面中的讨论。 | No;默认为 true |
createUnicodeExtraFields | 是否创建 Unicode 额外字段以在条目的元数据中再次存储文件名。可能的值 never 、always 和 not-encodeable ,这将仅在文件名无法编码时添加 Unicode 额外字段。另请参见 zipTask 页面中的讨论。 |
No; 默认为 never |
fallbacktoUTF8 | 如果无法使用指定的编码对文件名进行编码,是否使用 UTF-8 和语言编码标志而不是指定的编码。从 Ant1.8.0 开始引入该参数。另请参见 zipTask 页面中的讨论。 | No; 默认为 false |
mergeClassPathAttributes | 是否合并在不同清单中找到的 Class-Path attribute(如果合并清单)。如果为 false,则仅保留上次合并的清单的 attribute 。从 Ant 1.8.0 开始引入该参数。除非您还将 flattenAttributes 设置为 true,否则这可能会导致清单包含多个违反清单规范的 Class-Path attribute。 |
No; 默认为 false |
flattenAttributes | 是否将 section 中多次出现的 attribute(这只能发生在 Class-Path attribute 中)合并到单个 attribute 中。从 Ant 1.8.0 开始引入该参数。 |
No; 默认为 false |
zip64Mode | 何时对条目使用 Zip64 扩展名。可能的值有 never 、always 和 as-needed 。从 Ant 1.9.1 开始引入该参数。另请参见 zipTask 页面中的讨论。 |
No; 默认为 never |
指定为嵌套元素的参数
-
lib
。嵌套的
元素指定一个文件集。此文件集中包含的所有文件都将位于 war 文件的WEB-INF/lib
目录中。 -
classes
。嵌套
元素指定一个文件集。此文件集中包含的所有文件都将位于 war 文件的WEB-INF/classes
目录中。 -
webinf
。嵌套的
元素指定一个文件集。此文件集中包含的所有文件都将位于 war 文件的WEB-INF
目录中。如果此文件集包含名为web.xml
的文件,则该文件将被忽略,您将收到警告。 -
metainf
。嵌套的
元素指定一个文件集。此文件集中包含的所有文件都将位于 war 文件的META-INF
目录中。如果此文件集包含一个名为MANIFEST.MF
的文件,则该文件将被忽略,您将收到警告。 -
manifest
,indexjars
,service
。这些参数集成自 jar Task。
示例
在项目的 base 目录中采用以下结构:
thirdparty/libs/jdbc1.jar
thirdparty/libs/jdbc2.jar
build/main/com/myco/myapp/Servlet.class
src/metadata/myapp.xml
src/html/myapp/index.html
src/jsp/myapp/front.jsp
src/graphics/images/gifs/small/logo.gif
src/graphics/images/gifs/large/logo.gif
然后使用创建 war 文件 myapp.war:
将包括:
WEB-INF/web.xml
WEB-INF/lib/jdbc2.jar
WEB-INF/classes/com/myco/myapp/Servlet.class
META-INF/MANIFEST.MF
index.html
front.jsp
images/small/logo.gif
images/large/logo.gif
使用 Ant 的默认清单文件。WEB-INF/web.xml
的内容与 src/metadata/myapp.xml
相同。
我们经常收到错误报告,称此 Task 正在将 WEB-INF
目录创建为 web-inf
(全部小写),因此您的 webapp 无法工作是我们的错。这些抱怨的原因在于 WinZip,它将一个全大写的目录转换为一个全小写的目录。在提交另一份报告之前,请检查 jar xvf yourwebapp.war
是否显示相同的行为。Winzip 有一个允许所有大写名称的选项(默认情况下是关闭的!)。可通过以下方式启用:菜单“Options”→ “Configuration”,“View” 选项卡页,然后“General”组框中有一个名为“Allow all uppercase file names”的选项。
Zip
该 Task 用于创建 zip压缩文件。basedir attribute 表示是对哪个目录进行压缩。请注意,文件权限不会存储在生成的 zip 文件中。
可以通过 includes
、includesfile
、excludes
、excludesfile
和 defaultexcludes
这些 attribute 来选择文件集合中哪些文件会被打包到目标 zip 文件中。includes
或 includesfile
attribute 用于指定需要进行压缩的文件。exclude
或 excludesfile
attribute 用于指定压缩时需要排除的文件,这也是通过模式匹配来实现的。最后,使用 defaultexcludes
可以指定是否要使用默认排除。请参阅关于基于目录的 Task 、包含/排除文件的工作方式以及如何编写模式的部分内容。
此 Task 形成一个隐式的 FileSet 数据类型,并支持
(dir 变为 basedir)的大多数 attribute 以及
嵌套的
、
和
元素。或者,可以在其中放置嵌套的文件集或对文件集的引用。在这种情况下,basedir
是可选的;仅当设置了 basedir
时才使用隐式文件集。您可以使用隐式文件集的任意组合(带有 basedir
文件集,以及可选 attribute(如 includes
)和可选子元素(如
);显式的嵌套
元素,需要至少指定一个文件集。zip 文件将只反映每个文件集中文件的相对路径。zip
Task 及其派生 Task 可以识别一种名为 zipfileset
的特殊形文件集,该文件集具有附加属性(如下所述)。
zip
Task 还支持将多个 zip 文件合并到 zip 文件中。这可以通过任何嵌套文件集的 src
attribute 实现,也可以通过使用特殊的嵌套文件集 zipgroupfileset
实现。
update
参数表示当 zip 文件已经存在时会发生什么。设置为 true
时,将使用指定的文件更新 zip 文件(添加新文件,旧文件将替换为新版本),设置为 false
(默认值)时,如果要添加到存档中的任何文件都比存档中的条目新,则会覆盖整个 zip 文件。请注意,zip 文件以 2 秒的粒度存储文件修改时间。如果文件比存档中的条目新的少 2 秒,Apache Ant 将会认为它不需要更新。
whenempty
参数表示当没有匹配文件时会发生什么。如果设置为 skip
(默认设置),则不会创建 zip 并发出警告。如果设置为 fail
,则不会创建 Zip,生成将因错误而停止。如果设置为 create
,将创建一个空的 zip 文件(显式为零条目),兼容的 zip 操作工具应将其识别为空的 zip 文件。
zip
Task 现在将对文件名使用默认 JVM 字符编码,这与命令行的 zip 工具一致,但如果试图从 Java 中打开它们且文件名包含非 US-ASCII 字符,则会导致问题。使用 encoding
attribute 并将其设置为 UTF8
以创建可由 Java 安全读取的 zip 文件。有关更完整的讨论,请参见下文。
自 Ant 1.5.2 以来,
可以在归档文件中存储 Unix 权限(请参阅
的 filemode
和 dirmode
attribute 说明)。不幸的是,没有可移植的方式来存储这些权限。Ant 使用 InfoZip 实现 zip 和 unzip 命令时所使用的算法,这些是许多 Unix-like 系统的默认 zip 和 unzip 版本。
请注意,zip 格式允许同一个归档文件中存在多个相同完全限定名的文件。如果要避免此行为,必须将 duplicate
attribute 设置为默认值(add
)以外的值 。
还请注意,在应用文件的时区偏移计算时,不同的 zip 工具处理时间戳的方式不同。一些 zip 库将存储从文件系统读取的时间戳,而其他库将在读取和写入文件时修改时间戳,以使所有时间戳使用相同的时区。由一个库创建的 zip 存档在由另一个库提取时可能会提取具有“错误时间戳”的文件。
Ant 的 ZIP 类使用与 InfoZip工具和 zlib(时间戳得到调整)相同的算法,Windows 的 compressed folders
函数和 WinZip 不会更改时间戳。这意味着对由 Windows 的 compressed folders
函数创建的文件使用 unzip
Task 可能会创建时间戳错误的文件,如果使用 Windows 的函数提取 Ant 生成的 zip 存档文件,情况也是如此。
参数
Attribute | Description | Required |
---|---|---|
destfile | 要创建的 zip 文件路径。 | Yes |
basedir | 要压缩成 zip 文件的基础目录,即该目录下的文件将压缩到 zip 文件中。 | No |
compress | 不仅存储数据,还压缩数据。除非将 keepcompression attribute 设置为 false ,否则这将应用于整个存档,而不仅仅是更新时添加的文件。 |
No;默认为 true |
keepcompression | 对于来自现有归档文件的条目(如嵌套 zipfilesets 或更新归档文件时),保持压缩原样,而不是使用 compress attribute 。从 Ant 1.6 开始。 |
No;默认为 false |
encoding | 用于存档中文件名的字符编码。请参考支持的编码值列表。 | No;默认为默认的 JVM 字符编码 |
filesonly | 仅保存文件条目。 | No;默认为 false |
includes | 需要包含的文件 pattern 列表,列表中的各 pattern 之间使用逗号或空格分隔。 | No;默认为所有(**) |
includesfile | 一个文件名。该文件中的每一行将被当做一个需要包含的文件 pattern。 | No |
excludes | 需要排除的文件 pattern 列表,列表中的各 pattern 之间使用逗号或空格分隔。 | No; 默认为 defaultexcludes attribue 的值,如果defaultexcludes 为 no 的话,则为 none |
excludesfile | 一个文件名。改文件中的每一行将被当做一个需要排除的文件 pattern。 | No |
defaultexcludes | 表明是否使用默认的排除。值可为 yes 或 no 。 |
No; 默认为 yes |
update | 如果目标文件已存在,指示是否更新或覆盖目标文件。 | No;默认为 false |
whenempty | 指定当没有文件匹配时的行为。有效值为 fail 、skip 和 create 。 |
No;默认为 skip |
duplicate | 指定当发现重复文件时的行为。有效值为 add 、preserve 和 fail 。 |
No;默认为 add |
roundup | 是否将文件修改时间四舍五入到下一个偶数秒。zip归档文件时以 2 秒的粒度存储文件修改时间,因此时间将向上或向下取整。如果向下取整,则当您重新运行 Task 时,归档文件将始终看起来过时,因此默认为向上取整。四舍五入可能会导致不同类型的问题,如 web 归档文件中的 JSP,这些问题似乎比预编译页面更为新,从而导致预编译无效。从 Ant 1.6.2 开始引入该参数。 | No;默认为 true |
comment | 存储到归档中的注释。自 Ant 1.6.3 开始引入该参数。 | No |
level | 指定执行文件压缩的级别。有效值范围从 0(无压缩/最快)到 9(最大压缩/最慢)。从 Ant 1.7 开始引入该参数。 | No |
preserve0permissions | 在更新存档文件或添加来自其他存档文件的条目时,Ant 将假定 Unix 权限值为0(不允许任何人对文件/目录执行任何操作),这意味着权限根本没有被存储,而不是真正的权限,而是将应用其自己的默认值。如果确实要保留原始权限,请将此属性设置为 true。自 Ant 1.8.0 开始引入该参数。 | No;默认为 false |
useLanguageEncodingFlag | 如果编码是 UTF-8,是否设置语言编码标志(flag)。如果编码不是 UTF-8,此设置没有任何效果。自 Ant 1.8.0 开始引入该参数。参见下面的描述。 | No;默认为 true |
createUnicodeExtraFields | 是否创建 Unicode 额外字段以在条目的元数据中再次存储文件名。可能的值 never 、always 和 not-encodeable ,这将仅在文件名无法编码时添加 Unicode 额外字段。参考下面的描述。 |
No;默认为 never |
fallbacktoUTF8 | 如果无法使用指定的编码对文件名进行编码,是否使用 UTF-8 和语言编码标志而不是指定的编码。从 Ant1.8.0 开始引入该参数。参考下面的描述。 | No;默认为 false |
zip64Mode | 何时对条目使用 Zip64 扩展名。可能的值有 never 、always 和 as-needed 。从 Ant 1.9.1 开始引入该参数。参考下面的描述。 |
No;默认为 as-needed |
文件名编码
传统上,zip 存档格式使用 CodePage 437 作为文件名的编码,这对于许多国际字符集来说是不够的。随着时间的推移,不同的架构师选择了不同的方法来解决这个限制,例如 java.util.zip包只是使用 UTF-8 作为其编码。自 Ant1.4 以来,Ant 一直提供 zip
和 unzip
Task 的 encoding
attribute 来作为显式指定要使用(或预期)的编码的一种方式。它默认为对 zip 文件使用默认的 JVM 字符编码, UTF-8 用于 jar
和其他类似 jar
的 Task(War、Ear等)以及 unzip
系列的 Task。
zip 规范的最新版本引入了一种称为“语言编码标志”(language encoding flag
)的东西,该 flag
可用于表示文件名已使用 UTF-8 编码。自 Ant 1.8.0 以来,Ant 编写的所有 zip、jar 和类似档案都将设置此标志,如果编码设置为 UTF-8。我们与现有归档程序的互操作性测试没有显示任何不良影响(事实上,到目前为止,大多数归档程序都忽略了该标志),但是如果遇到问题,您可以通过在 zip
Task 中将属性 useLanguageEncodingFlag
设置为 false
来关闭语言编码标志。unzip
Task(和类似 Task)将识别“语言编码标志”,并忽略 Task 上的编码集(如果已找到)。
InfoZip 开发人员引入了新的 ZIP 额外字段,可用于将额外的 UTF-8 编码文件名添加到条目的元数据中。大多数归档程序忽略这些额外字段。自 Ant 1.8.0 以来,zip 系列的 Task 支持 createUnicodeExtraFields
选项,该选项使 Ant 为所有条目(always
)或仅为名称无法使用指定编码(not-encodeable
)进行编码的条目写入这些额外字段。由于额外字段会创建更大的存档,因此默认为 never
。
zip 的 fallbackToUTF8
attribute 在大多数情况下可用于创建使用指定编码的存档,但使用 UTF-8 和“语言编码标志”的文件名不能使用指定的编码。默认情况下,unzip Task 默认将识别 Unicode 额外字段并从中读取文件名信息,除非将可选的 scanForUnicodeExtraFields
attribute 设置为 false。
使用建议
最佳标志设置取决于您期望用来压缩和解压 zip 存档的解压缩程序。以下是一些测试结果,这些结果可能会被每个工具的更高版本所取代。
jar 可执行文件或从 CLASSPATH 读取 jar 所使用的 java.util.zip 包在读取和写入 UTF-8 名称时,该包它不设置或识别任何标志或 unicode 额外字段。
自 Java 7 以来,java.util.zip 默认写入 UTF-8 并使用“语言编码标志”。在通过新构造函数读取/写入 zip 时,可以指定不同的编码。现在,包在读取时识别“语言编码标志”,并忽略 Unicode 额外字段。
7Zip 默认情况下写入 CodePage 437,但在使用 UTF-8 和“语言编码标志”写入条目时,无法编码为 CodePage 437(类似于
fallbacktoUTF8
设置为true
的 zip Task)。它在读取时识别“语言编码标志”,并忽略 Unicode 额外字段。WinZip 默认情况下写入 CodePage 437 并使用 Unicode 额外字段。它在读取时识别 Unicode 额外字段和“语言编码标志”。
Windows 的“压缩文件夹”功能不识别任何标志或额外字段,并使用默认平台编码创建归档文件,并希望在读取归档文件时使用该编码。
基于 InfoZip 的工具可以识别和写入 Unicode 额外字段和“语言编码标志”这两种方式,这是一个编译时选项,取决于平台,因此结果可能会有所不同。
PKWARE zip工具可以识别 Unicode 额外字段和“语言编码标志”这两种方式,更倾向于使用“语言编码标志”。如果可能,他们使用 CodePage 437,还会为无法编码为 CodePage 437 的文件名使用 UTF-8 以及的“语言编码标志”来创建归档。
那么,具体怎么办呢?如果您正在创建 jar,那么 java.util.zip 是主要工具。我们建议将编码设置为 UTF-8,并保持启用“语言编码标志”。该标志不会帮助或损害 Java 7 之前的 java.util.zip,但支持它的解压缩程序将显示正确的文件名。
为了实现最大的互操作性,最好将编码设置为 UTF-8,启用“语言编码标志”,并在编写 zip 时创建 Unicode 额外字段。应该使用 java.util.zip、7Zip、WinZIP、PKWARE 工具和最有可能的 Infozip工具正确提取这些归档文件。不过,如果没有 Unicode 额外字段,它们将无法使用 Windows 的“压缩文件夹”功能,并且会比归档文件更大。
如果 Windows 的“压缩文件夹”是主要工具,那么最好的选择是显式地将编码设置为目标平台。您可能希望启用创建 Unicode 额外字段,以便支持这些字段的工具能够正确提取文件名。
Zip64 扩展
Zip64 扩展提供了一种方法来创建大于 4GB 的归档文件或保存超过 65535 个条目,或者使用 ZIP 扩展字段机制添加大于 4GB 的单个条目。大多数现代 ZIP 实现都支持这些扩展。
当 Ant 将压缩条目写入它创建的归档文件时,它在写入条目之前不知道条目的压缩大小。不幸的是,在写入条目内容之前,必须决定是否写入 Zip64 额外字段。Ant 1.9.0 引入了对 Zip64 扩展的支持,但没有提供对其使用的任何控制。自 Ant 1.9.1 以来,zip 系列 Task 中添加了一个新的 zip64mode
attribute。它支持三个值:
-
never
意味着不会写入 Zip64 额外字段。这是 Ant 在 1.9.0 之前的行为,也是自 Ant 1.9.1 以来 jar、ear 和 war 的默认行为。 -
always
意味着为所有条目写入 Zip64 额外字段。 -
as-needed
意味着所有压缩条目的 Zip64 额外字段都会写入“本地文件头”(默认情况下,这些都是文件,但不是目录),但只有在条目确实需要 Zip64 功能时才会写入中心目录。这是 Ant 1.9.0 的默认行为,仍然是 zipTask 的默认行为。
如果您不知道存档是否会超出传统 zip文件的限制,但又不想浪费太多空间(Zip64 扩展占用额外空间),那么 as-needed
提供了一个很好的折衷方案。不幸的是,一些 zip 实现不理解 Zip64 额外字段,或者无法解析某类存档(这些存档的存在含有额外字段的本地文件头,但这些文件头没有出现中心目录中),其中一个实现是 java 5 的 java.util.zip 包,这就是 jar Task 默认为 never
的原因。使用 as-needed
创建的存档可以在 Java 6 及更高版本中读取而不会出现问题。
指定为嵌套元素的参数
- 任何资源集合。资源集合用于选择要归档的文件组。在 Ant1.7 之前,只有
和
被支持作为嵌套元素。 -
zipgroupfileset
。
允许将多个 zip文件合并到存档中。在此文件集中找到的每个文件都将以与添加zipfileset
src
文件相同的方式添加到存档中。
是一个 fileset,支持其所有 attribute 和嵌套元素。
示例
将 htdocs/manual 目录中的所有文件压缩到 ${dist}
目录中名为 manual.zip 的文件中。
将 htdocs/manual 目录中的所有文件压缩到 ${dist}
目录中名为 manual.zip 的文件中。如果 manual.zip 不存在,则创建它;否则,它将使用新的/更改的文件进行更新。
压缩 htdocs/manual 目录中的所有文件,但不包括该目录 mydocs 中的文件或名为 todo.html 的文件。
压缩 htdocs/manual 目录中的所有文件,但仅压缩目录 api 下的 html 文件,并排除名为 todo.html 的文件。
压缩 htdocs/manual 目录中的所有文件,并在当前目录中添加文件 ChangeLog.txt。ChangeLog.txt 将添加到 zip文件的顶部,就像它位于 htdocs/manual/ChangeLog.txt 一样。
将 htdocs/manual 目录中的所有文件压缩到归档文件中的 docs/user-guide 目录中,将当前目录中的文件 ChangeLog27.txt 添加为 docs/ChangeLog.txt,并将examples.zip 中的所有 html 文件包含在 docs/examples 下。
存档可能最终包含以下文件:
docs/user-guide/html/index.html
docs/ChangeLog.txt
docs/examples/index.html
将 htdocs/manual 目录中的所有文件压缩到归档文件中的 docs/user-guide 目录中,并将所有文件包含在与 examples*.zip
匹配的任何文件中,例如examples1.zip 或 examples_for_brian.zip 中的所有文件。
同样的道理也可以通过
将 tar 归档文件重新打包为 zip 归档文件。如果 Unix 文件权限已作为 tar 文件的一部分存储,则它们将保留在生成的 zip 存档中。
Signjar
对 jar 文件进行签名可以允许用户对发布者进行身份验证。使用 jarsigner
命令行工具对 jar 文件进行签名。signjar
Task 将在 jar
attribute 中包含一个待签名的 jar 文件的路径,以及一个可选的 destDir
或 signedjar
attribute。还支持嵌套路径;这里只允许使用(可选)destDir
。如果未提供目标目录或显式 jar 文件路径,jar 文件将就地签名。依赖规则如下:
- 创建/签名不存在的目标 jar
- 已创建/签署过期的目标 jar
- 如果目标文件和源文件相同,并且
lazy
为true
,则仅当 jar 不包含此别名的签名时,才会对其进行签名。 - 如果目标文件和源文件相同,并且
lazy
为false
,则对 jar 进行签名。
参数
Attribute | Description | Required |
---|---|---|
jar | 待签名的 jar 文件路径。 | Yes,除非使用了嵌套路径 |
alias | 要签名的别名。 | Yes |
storepass | 密钥存储库完整性的密码。 Ant 不会使用 -storepass 命令行参数,而是在提示输入密码时将密码发送给 jarsigner 。 |
Yes |
keystore | keystore 位置。 | No |
storetype | keystore 类型。 | No |
keypass | 私钥(如果不同)的密码。 | No |
sigfile | .SF/.DSA 文件的名称。 |
No |
signedjar | 签名后的 jar 文件路径,仅当设置了 jar attribute 时才可以设置该 attribute。 | No |
verbose | 签名时是否输出详情(true |false )。 |
No;默认为 false |
strict | 签名时是否进行严格检查(true |false ),自 Ant 1.9.1 开始引入该 attribute。 |
No; default false |
internalsf | 在签名块内部是否包含 .SF 文件(true |false )。 |
No; default false |
sectionsonly | 是否仅计算 sections 的 hash 值(而不计算整个清单的 hash 值)(true |false )。 |
No;默认为 false |
lazy | 这仅在目标 JAR 与源 JAR 路径一样时发挥作用,用于控制是否进行签名操作。当该 attribute 为 true ,则仅当 jar 文件中不包含此别名的签名时,才会对其进行签名;当该 attribute 为 false ,则对 jar 文件进行签名。 |
No;默认为 false |
maxmemory | 指定 jarsigner JVM 将使用的最大内存。以标准 Java 内存规范的样式指定(如 128m = 128 MBytes)。 | No |
preservelastmodified | 为签名文件指定与原始 jar 文件相同的上次修改时间。 | No;默认为 false |
tsaurl | Java 5+ 中加了时间戳的 JAR 文件的时间戳权限的 URL。 | No |
tsacert | Java 5+ 中加了时间戳的 JAR 文件的时间戳权限密钥库中的别名。 | No |
tsaproxyhost | 连接到 TSA 服务器时要使用的代理主机名。 | No |
tsaproxyport | 连接到 TSA 服务器时要使用的代理端口。 | No |
executable | 指定一个特定的 jarsigner 可执行文件来代替默认二进制文件(与 Apache Ant 运行在同一个 JDK 中)。必须支持与 Sun JDK jarsigner 命令相同的命令行选项。从 Ant 1.8.0 开始引入该 attribute。 |
No |
force | 是否强制对 jar 文件进行签名,即使该文件似乎没有过期或已签名。从 Ant 1.8.0 开始引入该 attribute。 | No;默认为 false |
sigalg | 签名算法名。 | No |
digestalg | 摘要算法名。 | No |
tsadigestalg | TSA 摘要算法名。自 Ant 1.10.2 开始引入该 attribute。 | No |
providername | 安全属性文件中列出的加密服务提供程序的名称。从 Ant 1.10.6 开始引入该 attribute。 | No |
providerclass | 安全属性文件中未列出加密服务提供程序的主类文件的名称。从 Ant 1.10.6 开始引入该 attribute。 | No |
providerarg | 表示 provider_class_name 的构造函数的可选字符串输入参数。如果未设置 providerclass ,则忽略。从 Ant 1.10.6 开始引入该 attribute。 |
No |
指定为嵌套元素的参数
Attribute | Description | Required |
---|---|---|
path | 需要进行签名的批量 jar 文件。从 Ant 1.7 开始。 | No |
fileset | 需要进行签名的批量 jar 文件集。 | No |
mapper | 签名时用于重命名 jar 文件的一个映射。 | No,只能提供一个。 |
sysproperty | JVM 系统属性,使用 Ant 环境变量的语法。 | No,只能提供一个。 |
arg | 使用该元素指定通过 attribute 不显式支持的 keytool 命令行参数。从 Ant 1.10.6 开始。 | No |
示例
有关生成代码签名证书的说明,请参阅 keytool 文档和/或证书颁发机构的说明。
使用别名 apache-group 对 ant.jar 进行签名,通过 secret
密码访问密钥库和私钥。
对与 dist/***/.jar
模式匹配的所有 jar 文件进行签名,将它们复制到随后的 signed
目录中。
意味着它们将全部复制到此目录,而不是复制到子目录。
在 dist/***/.jar
中对所有 jar 文件进行就地签名。使用 lazy 签名,因此仅当文件尚未签名时才会对其进行签名。
使用摘要算法 SHA1 和签名算法 MD5withRSA 对 dist/***.jar
中的所有 jar 文件进行签名。当您想要使用 JDK 7 jarsigner(默认使用 SHA256 和SHA256withRSA)创建将部署在不支持 SHA256 和 SHA256withRSA 的平台上的签名 jar 时,这一点尤其有用。
关于时间戳签名
时间戳记录签名发生的日期和时间,允许在该时间点验证签名。使用受信任的时间戳,用户可以验证签名是否发生在证书过期或吊销之前。如果没有此时间戳,用户只能在其当前日期验证签名。
Java 5 中引入了时间戳 jar 文件;从 Ant 1.7 开始支持它们。自 Ant 1.9.5 以来,未经验证的代理可用于访问 TSA。一般公共时间戳权限包括:
- http://timestamp.verisign.com
- http://tsa.starfieldtech.com
- https://timestamp.geotrust.com/tsa
- 其他(请参阅您的证书颁发机构)
还有一些不常用的归档解压缩相关的 Task:Ear、Tar、GZip/BZip2/XZ、Unjar、Unwar、Untar、Unzip、GUnzip/BUnzip2/UnXZ。这里就不做详细介绍了,详情请参考相关文档。