AO Ant Tasks

project: current stablemanagement: productionpackaging: active
java: >= 11semantic versioning: 2.0.0license: LGPL v3

BuildMaven CentralQuality Gate StatusLines of Code
Reliability RatingSecurity RatingMaintainability RatingCoverage

Ant tasks used in building AO-supported projects.


  • Fine-grained management of last-modified times within *.aar, *.jar, *.war, and *.zip files for optimum reproducibility and publishability.
  • Generate directory-only ZIP files with a reference timestamp to be able to manipulate ZIP file structure reproducibly while also not losing per-entry timestamps.
  • SEO filter Javadocs: Canonical URLs, selective rel="nofollow", Sitemaps, and Google Analytics tracking code.


Our immediate goal is to have efficient sitemaps for generated Javadocs. The sitemaps must provide accurate last-modified timestamps for generated pages. Our current implementation of reproducible builds is losing last-modified information.

More broadly, we desire accurate last-modified times for all project resources deployed in *.aar, *.jar, *.war, and *.zip files. This can have implications for web content modeling, web resource caching, and the resulting sitemap generation.

Our Solution

Leveraging the Apache Ant tasks provided by this project, our Jenkins builds will now compare the AAR/JAR/WAR/ZIP files between the last successful build and the current build. When the entry content is identical to the previous build, the entry will be modified in-place to have the same timestamp as the previous build. Thus, modified times will be carried through from build to build so long as the content has not changed. If the entry is new to a build, it will retain the timestamp resulting from ${} as is already done.

Our release builds do not use this optimization. They use standard reproducible timestamps, typically derived from ${git.commit.time}.

This is only an optimization to assist crawlers in identifying new content more efficiently. We only publish content from our SNAPSHOT (or POST-SNAPSHOT) builds. These snapshots are typically published by Jenkins (which will contain the patched modification times), but may also be published directly by developers (which will use standard reproducible timestamps).

Why Ant Tasks Instead of Maven Plugin?

We have implemented this as Ant tasks instead of a Maven plugin because the task is used to process its own artifacts. While we use the tasks via Apache Maven AntRun Plugin, the versatility of TaskDef Task allows us to pick-up the artifact of the current build on the classpath.