Since some time I set up new Java projects with Maven. Additionally I migrated some old ones to Maven. The main issue was dependency handling and building. No more manual writting/copying of Ant build.xml’s. This works well as long you need libraries/artefacts that can be found in maven repository and/or the ones not available are your own. In the latter case they reside in your local repository and are accessible by other projects. Up until now this worked well since such dependencies only existed inside one project and could be resolved. However in the OpenSource world there comes a time where this is no longer possible. This happened, when I wanted to use ch.sahits.sahitsUtils in my game project OpenPatrician. The logical conclusion was to publish the artefact to a maven repository. This however proved a little more difficult.
The first step in such things is always to search the net, where I found some few hints. Some brought me a step further. The first realisation I had was that though the software is OpenSource the way into a repository is not. But it is not that complicated. You have to decide on a repository where you want to deploy your release into. Most repositories are interconnected, meaning they synchronize new artefacts, so your stuff should be promoted through the whole Maven ecosystem within some days. For OpenSource software the obvious choice seems to be the OSS repository of Sonatype. Whatever repository you choose the first step is an administrative one: Create an account and state your intentions on adding a project.
The following links helped enormously in the process to get my artefact into the repository:
- Description of the Maven Release Cycle
- How To Generate PGP Signatures With Maven
- Sonatype OSS Repository User Guide
Normally the repository has some policies as to the minimal requirements of your pom file. I figure the ones of Sonatype to be reasonable. In the case of the sahitsUtils project this resulted in the following pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>ch.sahits</groupId> <artifactId>sahitsUtil</artifactId> <version>1.2.4-SNAPSHOT</version> <name>sahitsUtil</name> <description>Utilities used in different projects of Sahits GmbH</description> <parent> <groupId>org.sonatype.oss</groupId> <artifactId>oss-parent</artifactId> <version>7</version> </parent> <developers> <developer> <id>hotzst</id> <name>Andi Hotz</name> <organization>Sahits GmbH</organization> </developer> </developers> <licenses> <license> <name>GNU Library General Public License (GPL), Version 2.0</name> <url>http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt</url> <distribution>repo</distribution> </license> <license> <name>Lesser General Public License (LGPL)), Version 2.0</name> <url>http://www.gnu.org/licenses/old-licenses/lgpl-2.0.txt</url> <distribution>repo</distribution> </license> </licenses> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.5</source> <target>1.5</target> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-javadoc-plugin</artifactId> <configuration> <show>private</show> <nohelp>true</nohelp> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-release-plugin</artifactId> <configuration> <tagBase>https://sahitsutil.svn.sourceforge.net/svnroot/sahitsutil/tags</tagBase> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-gpg-plugin</artifactId> <executions> <execution> <id>sign-artifacts</id> <phase>verify</phase> <goals> <goal>sign</goal> </goals> </execution> </executions> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.8.1</version> </dependency> </dependencies> <organization> <name>Sahits GmbH</name> </organization> <scm> <url>https://sahitsutil.svn.sourceforge.net/svnroot/sahitsutil/trunk</url> <connection>scm:svn:https://sahitsutil.svn.sourceforge.net/svnroot/sahitsutil/trunk</connection> <developerConnection>scm:svn:https://sahitsutil.svn.sourceforge.net/svnroot/sahitsutil/trunk</developerConnection> </scm> <distributionManagement> <repository> <id>sonatype-nexus-staging</id> <url>https://oss.sonatype.org/service/local/staging/deploy/maven2</url> </repository> <snapshotRepository> <id>sonatype-nexus-snapshots</id> <url>https://oss.sonatype.org/content/repositories/snapshots</url> </snapshotRepository> </distributionManagement> </project>
The standard procedure for releasing an artefact would be:
mvn release:clean release:prepare release:perform
The prepare goal checks your project and prepares it for releasing:
- Check that all the local resources are committed
- Check that all dependencies have a defined version (no SNAPSHOTs allowed)
- If your version is a SNAPSHOT version, remove the SNAPSHOT part
- Execute the tests against the changed pom.
- Commit the modified POM
- Create a tag using the configuration specified in scm (Note that tagBase was supplied in the configuration of maven-release-plugin)
- Increase the version
- Commit the modified POM
If you do not run
mvn release:prepare with the batch option -B, you are asked for:
- release version
- SCM release tag or label
- new development version
The proposed values most often are good defaults, so you can run this in batch mode. However if you have specified a passphrase for your private key, you cannot use batch mode, unless you specify it with
-Dgpg.passphrase=thephrase. The prepare step produces the artefacts for the pom, binary, source and javadoc along with the signature files.
Since this project was converted, the checkout in
mvn release:perform produces a non-default layout so this step fails. I therefore found it easier to bundle the artefacts in a jar and upload them manually to the repository. This worked perfectly as described.