Saturday, September 22, 2007

How to effectively use SNAPSHOT

Recently I showed how you can use the maven-release-plugin to create a release for your project. Now I would like to explain how to use maven to effectively use SNAPSHOT.

First what do I mean by SNAPSHOT? SNAPSHOT is a special version in maven that indicates the latest code; typically TRUNK or HEAD in your source control. With this version, maven will automatically grab the latest SNAPSHOT every time you build. On the other hand, when you are using 2.0, once maven has downloaded this artifact, it never tries to get a new 2.0.

Why should you use SNAPSHOT? You should use SNAPSHOT for rapidly moving code where bug fixes and enhancements are coming fast. Another reason is you should never require users of your project to checkout and build your code. EVER! I would venture to say that 50% of the open source projects I have had to checkout and build, have not initially built.

How to create a SNAPSHOT?
First you have to find a webserver to host the artifacts. I have typically used apache running on linux. I first create a folder under / called snapshots (owner:group equal to repoman:repoman) and then create a softlink (ln -s) under /var/www/html called snapshots (owner:group being root:root). So now you should have /var/www/html/snapshots --> /snapshots. For some examples of some public SNAPSHOT repositories check out Apache's and Codehaus.

Second you need to update your parent POM in order to properly use the maven-deploy-plugin. First make sure the version you are using includes -SNAPSHOT. For example something like 0.9.2-SNAPSHOT.

Third add the distributionManagement section to your parent POM to look something like this:

<distributionManagement>
<snapshotRepository>
<id>maven2-snapshot-repository</id>
<name>Maven2 Snapshot Repository</name>
<url>scp://host/snapshots/</url>
<uniqueVersion>false</uniqueVersion>
</snapshotRepository>
</distributionManagement>
This will use scp to upload the artifacts to the url //host/snapshots. The element that needs to receive the most of your attention is <uniqueVersion>. This value can either be true or false. When it is false the artifacts created will not be unique and will look something like this each time: myproject-0.9.2-SNAPSHOT. Use this to reduce disk usage. When it is set to true a unique version is created everytime. For example myproject-0.9.2-20070922.011633-1.jar and then the next build that day would be myproject-0.9.2-20070922.011633-2.jar.

Finally, the last thing is to set the username and password of the repository in your $USER_HOME/.m2/settings.xml file. This will be used by scp for authentication. To do this add the following in your settings.xml file:
<servers>
<server>
<id>maven2-snapshot-repository</id>
<username>repoman</username>
<password>mypassword</password>
</server>
<servers>
That is it. Now you are ready to run mvn deploy.

14 comments:

Rodrigo said...

Very good stuff here. Keep up the good work!!

Jeff Black said...

Any insight into using the webdav protocol deployment versus the scp way?

Jeffrey Paul Anderson said...

Thanks for making this simple to understand. The lifecycle phase "deploy" was confusing me because of the same terminology for deploying into a J2EE appserver. I never did get this to work, because our webserver has ssh service running on a different port, and I haven't figured out how to manage that with the combination of these two files. Moreover, I haven't figured out how to actually deploy to our appserver which is glassfish. Apparently Cargo can get this done for a bunch of appservers, but not glassfish. So for now I'm just scripting it with configurable shell scripts calling asadmin. Icky, but better than having to fire up our IDE.

Leader 4 success

patrice truong van nga said...

Hi Lorenzo thanks for this article.

I 'm just wondering, if you know what's the typical path to manage version with Maven.

Indeed with maven we can change the keyword SNAPSHOT by betaY, alphaY or rcZ

I want to know how to proceed to manage the version of a artifact and of its dependencies ....

For example
current Publish

1.0-SNAPSHOT 1.0-alpha1

1.0-SNAPSHOT 1.0-beta1

1.0-SNAPSHOT 1.0-rc1

1.0



Have you some experienced on it thanks in advance

jlorenzen said...

@patrice

We actually don't use those qualifiers (alpha1 or beta1); maybe we should.

I am not sure I quite understand your question, but you might be asking how you could combine SNAPSHOT and qualifiers like alpha1 or beta1.

If you look at the maven verifier plugin, they put the beta qualifier in the version section.
http://svn.apache.org/repos/asf/maven/plugins/trunk/maven-verifier-plugin/pom.xml.

<version$gt;1.0-beta-2-SNAPSHOT&lt/version&gt

Nitin Vikram said...

Thanks for writing about this importnt topic. It is really helpful.

rafa rob said...

This article helped me to better understand what's the use of SNAPSHOT.

I think there's an error in the part about : "When it is set to false a unique version is created everytime" should be true instead of false.

jlorenzen said...

Thanks rafa, your correct.

Dr.Drane said...

Aloha! First up, also many thanks for the article! It got me better understanding SNAPSHOTS. I didn't get how to put them in my nexus library, and now I do.

Though following your explanation I got an authentication error using scp which I copy pasted below. Any idea how I could solve this? Tried even with my personal and root accounts but still wasn't authenticated.

Best wishes,

Jochen

Error retrieving previous build number for artifact 'com.prefabSOFT:prefabSOFT-super-pom:pom': repository metadata for: 'snapshot com.prefabSOFT:prefabSOFT-super-pom:0.0.1-SNAPSHOT' could not be retrieved from repository: prefabSOFT-snapshot-repository due to an error: Authentication failed: The host was not known and was not accepted by the configuration: 46.51.173.123

reject HostKey: 46.51.173.123

jlorenzen said...

@Dr.Drane
If your repo is locked down, which it sounds like it is, then you need to specify the username and password in your settings.xml file in your .m2 home directory.

<server>
<id>repo-snapshots</id>
<username>drdrane</username>
<password>password</password>
</server>


There actually might be a better way now with maven 2.2.1 and 3, so I'd search google first.

André Pinheiro said...

Helpful as hell!!

Anonymous said...

Thanks a lot for uniqueVersion - saved me a lot of troubleshooting time.

Anonymous said...

Per artifactory setting uniqueVersions to false isn't supported anymore in maven 3.0.3.
http://wiki.jfrog.org/confluence/display/RTF/Local+Repositories

I had an issue with this but was able to get snapshots to work by updating my maven-deploy-plugin version to 2.7 (2.5 is the default as of today)

Anonymous said...

Maven snapshots waste a huge amount of my time ever day. This is just moronic stuff.