Ant
Deploying to OSSRH with Apache Ant - Introduction⚓︎
Apache Ant can be configured to fulfill the requirements for component deployment to the Central Repository in various ways. In fact Apache Ant itself is released to the Central Repository.
Apache Ant provides tasks for creating the components required. The deployment itself can be performed with Apache Ivy or the Aether Ant tasks. Eclipse Aether is the repository access component used in Maven 3+. The old Maven Ant tasks can be used as well although they are using components of the deprecated Maven 2.
In the following examples we will assume a project directory setup of
build.xml
pom.xml
src/
lib/
...
where the src
folder contains Java source code and the pom.xml
fulfills the
requirements. These locations are stored
in properties in the build.xml file
<property name="src" location="src" />
<property name="build" location="build" />
<property name="dist" location="dist" />
A build
and a dist
and nested lib
folder are created in the init
task.
<target name="init">
<mkdir dir="${build}" />
<mkdir dir="${dist}/lib" />
</target>
and components coordinated and names are declared using Maven repository naming conventions
<!-- define Maven coordinates -->
<property name="groupId" value="com.juvenxu" />
<property name="artifactId" value="ant-demo" />
<property name="version" value="1.0-SNAPSHOT" />
<!-- define artifacts' name, which follows the convention of Maven -->
<property name="jar" value="${dist}/lib/${artifactId}-${version}.jar" />
<property name="javadoc-jar" value="${dist}/lib/${artifactId}-${version}-javadoc.jar" />
<property name="sources-jar" value="${dist}/lib/${artifactId}-${version}-sources.jar" />
The credentials for accessing OSSRH
are stored in the Maven settings.xml
for usage by the
Aether or Maven Ant tasks for simplicity. For Ivy usage a property file will be used.
Compilation and Jar Creation⚓︎
In our example we are compiling and creating the jar file with the following commands.
<target name="compile" depends="init">
<javac srcdir="${src}" destdir="${build}" />
</target>
<target name="jar" depends="compile">
<!-- build the main artifact -->
<jar jarfile="${jar}" basedir="${build}" />
</target>
The main output of this task is the jar file we are going to deploy using the
name defined in the jar
property locating the file in the dist/lib
folder,
where the deploy tasks will pick them up from.
Javadoc and Sources Jar Creation⚓︎
The JavaDoc and Sources jar creation is accomplished with the following defintion.
<target name="dist" depends="jar">
<!-- build the javadoc jar -->
<javadoc sourcepath="${src}" destdir="${dist}/javadoc" />
<jar jarfile="${javadoc-jar}">
<fileset dir="${dist}/javadoc" />
</jar>
<!-- build the sources jar -->
<jar jarfile="${sources-jar}">
<fileset dir="${src}" />
</jar>
</target>
Again the main result is the properly named jar files found in the dist/lib
folder.
Signing and Deployments Using the Maven Ant Tasks⚓︎
The Maven Ant tasks can be used to execute the Maven deploy plugin.
With the setup above and the Maven Ant tasks available on the classpath of your
Ant execution, you can define a stage
target to publish to OSSRH.
Note: As of February 2021, all new projects began being provisioned on https://s01.oss.sonatype.org/. If your project is not provisioned on https://s01.oss.sonatype.org/, you will want to reference the legacy host https://oss.sonatype.org/.
<project name="ant-demo" default="deploy" basedir="." xmlns:artifact="antlib:org.apache.maven.artifact.ant">
<!-- defined maven snapshots and staging repository id and url -->
<property name="ossrh-snapshots-repository-url"
value="https://s01.oss.sonatype.org/content/repositories/snapshots/" />
<property name="ossrh-staging-repository-url"
value="https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/" />
<!-- there server id in the Maven settings.xml -->
<property name="ossrh-server-id" value="ossrh" />
<target name="deploy" depends="dist" description="deploy snapshot version to Maven snapshot repository">
<artifact:mvn>
<arg value="org.apache.maven.plugins:maven-deploy-plugin:2.6:deploy-file" />
<arg value="-Durl=${ossrh-snapshots-repository-url}" />
<arg value="-DrepositoryId=${ossrh-server-id}" />
<arg value="-DpomFile=pom.xml" />
<arg value="-Dfile=${jar}" />
</artifact:mvn>
</target>
<!-- before this, update project version (both build.xml and pom.xml) from SNAPSHOT to RELEASE -->
<target name="stage" depends="dist" description="deploy release version to Maven staging repository">
<!-- sign and deploy the main artifact -->
<artifact:mvn>
<arg value="org.apache.maven.plugins:maven-gpg-plugin:1.3:sign-and-deploy-file" />
<arg value="-Durl=${ossrh-staging-repository-url}" />
<arg value="-DrepositoryId=${ossrh-server-id}" />
<arg value="-DpomFile=pom.xml" />
<arg value="-Dfile=${jar}" />
<arg value="-Pgpg" />
</artifact:mvn>
<!-- sign and deploy the sources artifact -->
<artifact:mvn>
<arg value="org.apache.maven.plugins:maven-gpg-plugin:1.3:sign-and-deploy-file" />
<arg value="-Durl=${ossrh-staging-repository-url}" />
<arg value="-DrepositoryId=${ossrh-server-id}" />
<arg value="-DpomFile=pom.xml" />
<arg value="-Dfile=${sources-jar}" />
<arg value="-Dclassifier=sources" />
<arg value="-Pgpg" />
</artifact:mvn>
<!-- sign and deploy the javadoc artifact -->
<artifact:mvn>
<arg value="org.apache.maven.plugins:maven-gpg-plugin:1.3:sign-and-deploy-file" />
<arg value="-Durl=${ossrh-staging-repository-url}" />
<arg value="-DrepositoryId=${ossrh-server-id}" />
<arg value="-DpomFile=pom.xml" />
<arg value="-Dfile=${javadoc-jar}" />
<arg value="-Dclassifier=javadoc" />
<arg value="-Pgpg" />
</artifact:mvn>
</target>
<target name="clean" description="clean up">
<delete dir="${build}" />
<delete dir="${dist}" />
</target>
</project>
You'll notice that the stage
target above calls artifact:mvn
three times, each time with an argument of -Pgpg
.
This assumes that you have created a profile called gpg
in your .m2/settings.xml
file. Using this profile, you can
specify the passphrase to unlock your private key. See below for an example settings.xml
:
<settings>
<servers>
<server>
<id>ossrh</id>
<username>token-username</username>
<password>token-password</password>
</server>
</servers>
<profiles>
<profile>
<id>gpg</id>
<properties>
<! -- Optionally specify a different path and name for the gpg executable
if it differs from the default of "gpg"
<gpg.executable>gpg2</gpg.executable>
-->
<gpg.passphrase>xxxxxx</gpg.passphrase>
</properties>
</profile>
</profiles>
</settings>
Do not use your login username and password in settings.xml
Please do not use your UI login username and password in settings.xml. Use the token that was previously generated.
Note also how the id
element in the server
block above matches the value of the ossrh-server-id
variable used in
build.xml
. This is how the ant tasks will look up your credentials when deploying to OSSRH.
Signing Components⚓︎
If you decide to use Ant directly to sign your components you can use the signer Ant task.
Deployments Using Apache Ivy⚓︎
Apache Ivy allows resolving as well a publishing components to a repository. The signed components can be deployed to OSSRH with the publish task.
Deployments Using the Aether Ant Tasks⚓︎
The Aether Ant tasks are using the
same component to interact with Maven repositories as Apache Maven -
Eclipse Aether. You can publish your signed components
with the deploy
task.