Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Difference between revisions of "Aether/Ant Tasks"

(Targets)
m (Scopes)
Line 245: Line 245:
 
Every target takes either a <code>scope</code> or <code>classpath</code> attribute that is used to limit the resulting dependency tree.  
 
Every target takes either a <code>scope</code> or <code>classpath</code> attribute that is used to limit the resulting dependency tree.  
  
* scope: This may take one of the values that are allowed for dependency definitions in the POM (compile, provided, runtime, test, system). The resolved dependencies will only contain dependencies that match the scope filter. The value of this attribute must enumerate scopes to include or exclude, with excludes being marked by starting with '!':  
+
* <code>scope</code>: This may take one of the values that are allowed for dependency definitions in the POM (<code>compile, provided, runtime, test, system</code>). The resolved dependencies will only contain dependencies that match the <code>scope</code> filter. The value of this attribute must enumerate scopes to include or exclude, with excludes being marked by starting with <code>!</code> :  
  
 
<pre>
 
<pre>

Revision as of 06:49, 10 July 2014

The Aether Ant Tasks serve the purpose to allow ant builds the usage of dependency resolution, installation and deployment via Aether.

The ant tasks use the maven-aether-provider to set up maven-like session and dependency resolution.

Installing Aether Ant Tasks

For convenience, Aether Ant Tasks and all its dependencies are packaged together as a single uber JAR file available from the download page or from Maven central.

There are two ways to use the tasks from your scripts.

Installing in Ant's lib directory

This is the simplest installation method but requires changes on every machine using the build file. You can place the JAR in your Ant lib directory, include it in the CLASSPATH environment variable, or pass it in to Ant using the -lib command line parameter.

Using this method, to make the tasks available in your build file, add the following namespace to the start of the file:

<project ... xmlns:artifact="antlib:org.eclipse.aether.ant">
  ...
</project>

Declaring a typedef

Using a typedef declaration allows you to store the Ant Tasks' library anywhere you like (such as source control) and put it's location in the build file. This can be used to bootstrap the tasks by using get to obtain the library, and then reference it from the build script.

The following example shows how to set it up, assuming the library is in the lib subdirectory of your current project.

<project ... xmlns:artifact="antlib:org.eclipse.aether.ant">
  ...
	<path id="aether-ant-tasks.classpath" path="antlib/aether-ant-tasks-uber.jar" />
	<typedef resource="org/eclipse/aether/ant/antlib.xml"
		uri="antlib:org.eclipse.aether.ant"
		classpathref="aether-ant-tasks.classpath" />
  ...
</project>

Automatically downloading aether-ant-tasks-{version}-uber.jar

You can configure your Ant build to automatically download Aether Ant Tasks.

<!-- Steps to take on initialization -->
<target name="init">
	<get src="http://search.maven.org/remotecontent?filepath=org/eclipse/aether/aether-ant-tasks/1.0.0.v20140518/aether-ant-tasks-1.0.0.v20140518-uber.jar"
		dest="antlib/aether-ant-tasks-uber.jar" verbose="true" skipexisting="true"/>
	<fail message="Checksum mismatch for 'antlib/aether-ant-tasks-uber.jar'. Please delete it and rerun ant to redownload.">
		<condition>
			<not>
	        	<checksum file="antlib/aether-ant-tasks-uber.jar" algorithm="SHA"
	        		property="95dadd03392a75564904da45108cf048abe6e5bb" verifyproperty="checksum.matches"/>
			</not>
		</condition>
	</fail>
	<artifact:pom file="pom.xml" />
	<artifact:resolve>
		<path refid="cp.compile" classpath="compile"/>
		<path refid="cp.test" classpath="test" />     		
		<path refid="cp.runtime" classpath="runtime"/>
	</artifact:resolve>
</target>

Then use the init target as a dependency like this:

<target name="build-project" depends="init">
    <javac ... />
</target>

Data Types

POMs

A POM is used by the Aether ant tasks as a reference for installation and deployment, but also may be a definition of dependencies to resolve. The key properties of a POM are the groupid, artifactid and version. These may be defined either by using a pom.xml file:

<pom file="pom.xml" />

or in-memory by directly specifying these in the element:

<pom groupid="gid" artifactid="aid" version="1" /> 

"In-Memory POMs" that specify the GAV directly cannot be used to install or deploy artifacts.

File-based POMs that are defined outside a task and do not define an id will be set as the 'default POM'. This POM is used by install or deploy tasks that do not have an explicit POM definition and is also used for resolve tasks without a dependency definition.

Artifacts

An artifact definition is mostly about defining the produced file, but also has to define where the artifacts will be placed inside the local repository and by which coordinates they might be picked up:

<artifact file="some.file" type="jar" classifier="sources" /> 

It is not strictly necessary to connect an artifact to a corresponding POM definition, as this connection is made on installation or deploy, but if an artifact has no connected POM it is not contained in the local reactor:

<artifact pom="pomid" file="some.file" type="jar" classifier="sources" /> 

Dependencies

Dependencies are defined by using groupId, artifactId and version coordinates:

<dependencies> 
<dependency groupid="gid" artifactid="aid" version="1" /> 
... 
</dependencies> 

Exclusions

Every <dependency> definition or <dependencies> container may define exclusions of the transitively resolved dependencies. Exclusions are also defined by using coordinates, but parts of the coordinates may be left blank to be treated as a wildcard:

<dependency groupid="gid" artifactid="aid" version="1"> 
<exclusion groupid="gid2" artifactid="aid2" classifier="shaded" extension="jar" /> 
<exclusion groupid="gid" /> 
<exclusion coords="gid:*:*:*" 
</dependency> 

Repositories

If no repositories are defined, only maven central is used to resolve dependencies. The default list of repositories is available from the reference 'aether.repositories' and can be overridden by specifying different repositories with that reference:

<remoterepos id="aether.repositories"> 
<remoterepo url="http://snapshots.repository.codehaus.org/maven2" releases="false" updates="never" checksums="fail"> 
<snapshots enabled="true" updates="always" /> 
</remoterepo> 
<remoterepo url="http://repository.codehaus.org/maven2" releases="true" snapshots="false" updates="never" checksums="fail"/> 
</remoterepos> 

<remoterepos> acts only as a container for <remoterepo> definitions. Checksum and Update Policy attributes in the main definition set the defaults. They may also be specified differently for snapshot or release resolution.

Tasks

In general, the tasks will accept explicit definition of data types inside the task element itself instead of using a reference attribute. All tasks will deal with a 'default POM' (a standalone, id-less <pom> definition using the file attribute to reference a real POM).


Installing artifacts

If you want to have ant builds produce artifacts that can be consumed by maven, you need to define and install a POM entity and the artifacts attached to that POM.

<pom file="pom.xml" id="pom"/> 
<artifacts id="attached"> 
<artifact file="classes.jar" /> 
<artifact file="javadoc.jar" classifier="javadoc" /> 
</artifacts> 

This defines a POM entity that uses the file 'pom.xml' as a source for its key properties, groupid, artifactid and version. It is not necessary for the artifact to be attached to a certain POM, as this connection will be made in the install task:

<install pomref="pom" artifactsref="attached" /> 

This task will install the POM file and all attached artifacts into the local repository, where they can be picked up by maven builds after that.

If a default POM was defined and no POM is given to the install task, it will use the default POM for installation.

Deploying artifacts

Deploying artifacts to a remote repository works in the same way as installing. The task needs POM and artifacts elements, and an additional target repository.

<pom file="pom.xml" id="pom"/> 
<artifacts id="attached"> 
<artifact file="classes.jar" /> 
<artifact file="javadoc.jar" classifier="javadoc" /> 
</artifacts> 
<remoterepo url="http://some.repository.invalid" id="dist" /> 
<deploy pomref="pom" artifactsref="attached" remoterepo="dist"/> 


Dependency Resolution

The base of the dependency resolution capabilities is a <dependencies> definition. This definition lists the direct dependencies that need to be resolved:

<dependencies id="deps.aether"> 
<dependency groupid="org.sonatype.aether" artifactid="aether-connector-file" version="1.11"/> 
</dependencies> 
<dependencies id="deps.maven"> 
<dependency groupid="org.apache.maven" artifactid="maven-aether-provider" version="3.0.3"/> 
</dependencies> 

The resolve task itself may directly specify the dependencies to resolve via a reference or an explicit <dependencies> definition:

<resolve> 
<dependencies> 
<dependencies refid="deps.aether" /> 
<dependencies refid="deps.maven" /> 
</dependencies> 
... 
</resolve> 

<resolve dependenciesref="deps.aether"> 
... 
</resolve> 

If no dependencies are given, the resolve task will use the default POM as a starting point for dependency resolution, if it is available.

Targets

Dependency resolution has three different targets:

  • Path: A classpath built from resolved dependencies references the artifacts inside the local repository.
  • Files: Given a layout, the dependencies' artifact files can be copied into a specified directory.
  • Properties: Adds user properties with keys containing the dependency id and the path inside the local repository as values.

These targets may be mixed and used multiple times for the same dependency resolution task:

<artifact:resolve> 
    <dependencies> 
        <dependency refid="deps.aether" /> 
        <dependency refid="deps.maven" /> 
    </dependencies> 
    <path refid="cp.compile" classpath="compile"/>
    <path refid="cp.test" classpath="test" />     		
    <path refid="cp.runtime" classpath="runtime"/>
    <files dir="somedir" /> 
</artifact:resolve> 
Scopes

Every target takes either a scope or classpath attribute that is used to limit the resulting dependency tree.

  • scope: This may take one of the values that are allowed for dependency definitions in the POM (compile, provided, runtime, test, system). The resolved dependencies will only contain dependencies that match the scope filter. The value of this attribute must enumerate scopes to include or exclude, with excludes being marked by starting with ! :
<path refid="cp.test" scope="provided,system,compile,test" /> 
<files scope="!test,!system" /> 
  • classpath: The classpath attribute is actually a shortcut for defining scopes:
    • compile equals scope="provided,system,compile"
    • runtime equals scope="compile,runtime"
    • test equals scope="provided,system,compile,runtime,test"
Path

To create a path from the resolved artifacts you have to set a reference id under which the path will be stored:

<path refid="cp" /> 
Files

The <files> target can copy and/or create a fileset from the resolved artifacts. To create a fileset, the 'refid'-attribute has to set:

<files refid="depfiles" /> 

To copy the files, a target directory has to be specified. A layout pattern can be defined to override the default layout:

<files dir="target/deps" layout="{groupId}/{artifactId}-{baseVersion}.{extension}"/> 

Available layout patterns:

  • \{groupId}: The groupId of the artifact.
  • \{groupIdDirs}: The groupId of the artifact where every part of the id is used as a directory (e.g. 'org.sonatype.aether' will yield three directories, 'org/sonatype/aether').
  • \{artifactId}: The artifactId of the artifact.
  • \{version}: The resolved version of the artifact. For snapshot versions, the SNAPSHOT part may be resolved into a unqique timestamp.
  • \{baseVersion}: The unresolved version of the artifact.
  • \{classifier}: The classifier of the artifact, e.g. 'javadoc', 'sources'.
  • \{extension}: The extension of the artifact.

The files target can also be advised to not copy the main jar, but source or javadoc via the 'attachment' attribute:

<files dir="target/sources" attachment="sources" layout="{groupId}/{artifactId}-{baseVersion}.{extension}"/> 
<files dir="target/deps" attachment="javadoc" layout="{groupId}/{artifactId}-{baseVersion}.{extension}"/> 
Properties

The properties target will take a prefix and create properties of the form "$\{prefix}.\{groupId}:\{artifactId}:\{extension}". A dependency resolution like

<resolve> 
<depencies> 
<dependency groupid="org.sonatype.aether" artifactid="aether-connector-file" version="1.11"/> 
</depencies> 
<properties prefix="resolved" /> 
</resolve> 

will create (among others) a property with the name "resolved.org.sonatype.aether:aether-connector-file:jar". It's value will be the path to the resolved artifact inside the local repository.

Reactor Support

By default, all dependency resolution is done by using the local repository. The Ant tasks are able to use locally produced artifacts and POMs in the dependency resolution by caching <pom> and <artifact> definitions if they are suitable to be used in the dependency collection process.

<pom>

Local POM definitions are used if they are referencing a POM file. Instead of resolving and downloading the dependencies' POM into the local repository, that file is used directly to build the POMs model and continue dependency resolution.

<artifact>

To enable the dependency resolution to add locally produced artifacts to the classpath or filesets, an artifact has to be defined by explicitely referencing a POM definition to make the connection between GAV and produced artifact.

Settings

The ant tasks will automatically pick up the default settings.xml in $\{user.home}/.m2/settings.xml, if it's available. System settings are read from the following locations in that order:

  1. $\{ant.home}/etc/settings.xml
  2. $\{maven.home}/etc/settings.xml
  3. $M2_HOME/conf/settings.xml

You can override the default settings by specifying a <settings> element:

<settings file="user-settings.xml" globalfile="global-settings.xml" /> 

Local Repository

There can only be one active local repository at a time. The default location is the directory .m2/repository in the user's home, which can be overridden in the settings file or by setting the property maven.repo.local. With the <localrepo> element, the location of the local repository can be changed in the build file:

<localrepo dir="${user.home}/.m2/repository" /> 

Proxies

<proxy host="localhost" port="8080" type="http" nonProxyHosts="localhost,127.0.0.1" /> 

Mirror definitions

A mirror specified in the settings will be picked automatically. You can also add a definition by using the <mirror> element:

<mirror id="nexus" url="http://localhost:8081/content/groups/public" mirrorOf="*"/> 

Authentication

The <authentication> element provides the means to set up authentication for remote repositories, proxies and mirrors. The server definitions in the settings.xml are picked up automatically whenever authentication for remote repositories is needed.

<authentication username="login" password="pw" id="auth"/> 
<authentication privateKeyFile="file.pk" passphrase="phrase" servers="distrepo" id="distauth"/> 

Authentication definitions are applied automatically if the repository id is contained in the servers attribute, but may also be applied excplicitely by supplying the auth attribute to repository, proxy or mirror definitions.

<authentication username="login" password="pw" id="authid" servers="rso" /> 
<proxy host="" port="" type="http" nonProxyHosts="foo,bar" auth="authid" /> 
<mirror url="" mirrorOf="" auth="authid" /> 
<remoterepo id="rso" url="http://repository.sonatype.org/" auth="authid" /> 

Examples

<project name="Aether Ant Tasks Example - with in-memory POM" target="default">
<pom groupid="gid" artifactid="aid" version="1" id="main"/> 

<!-- Add artifacts to Reactor (pom reference) --> 
<artifacts pom="main" id="attached"> 
<artifact file="build/classes.jar" /> 
<artifact file="build/sources.jar" classifier="sources" /> 
</artifacts> 

<target name="default"> 
<resolve> 
<dependencies> 
<dependency groupid="org.sonatype.aether" artifactid="aether-ant-tasks" version="1.0"/> 
</dependencies> 
<path refid="cp.compile" classpath="compile" /> 
</resolve> 
</target> 
<project> 
<project name="Aether Ant Tasks Example - with POM file" target="default"> 
<!-- Define default POM --> 
<pom file="poms/main.pom" /> 

<!-- Define artifacts --> 
<artifacts id="attached"> 
<artifact file="build/classes.jar" /> 
<artifact file="build/sources.jar" classifier="sources" /> 
</artifacts> 

<!-- Deploy repository --> 
<remoterepo url="http://some.deploy.repository/invalid" id="dist" /> 

<target name="default"> 
<!-- resolve classpath --> 
<resolve> 
<path refid="cp.compile" classpath="compile" /> 
<path refid="cp.test" classpath="test" /> 
</resolve> 

<!-- build/test/package jar and sources --> 
<!-- .... --> 

<!-- install/deploy POM and artifacts --> 
<install artifactsref="attached /> 
<deploy artifactsref="attached" remoterepo="dist"/> 
</target> 
<project> 

Back to the top