<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Sonatype Blog &#187; snapshot</title>
	<atom:link href="http://blog.sonatype.com/people/tag/snapshot/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.sonatype.com/people</link>
	<description>Sonatype is transforming software development with tools, information and services that enable organizations to build better software, faster, using open-source components.</description>
	<lastBuildDate>Thu, 16 May 2013 18:53:09 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>Best Practices for releasing with 3rd party SNAPSHOT dependencies</title>
		<link>http://blog.sonatype.com/people/2009/01/best-practices-for-releasing-with-3rd-party-snapshot-dependencies/</link>
		<comments>http://blog.sonatype.com/people/2009/01/best-practices-for-releasing-with-3rd-party-snapshot-dependencies/#comments</comments>
		<pubDate>Mon, 26 Jan 2009 17:33:22 +0000</pubDate>
		<dc:creator>Brian Fox</dc:creator>
				<category><![CDATA[How-To]]></category>
		<category><![CDATA[Maven]]></category>
		<category><![CDATA[Nexus]]></category>
		<category><![CDATA[best practice]]></category>
		<category><![CDATA[snapshot]]></category>

		<guid isPermaLink="false">http://blogs.sonatype.com/people/?p=1486</guid>
		<description><![CDATA[The Maven Release plugin enforces best practices for releasing Maven artifacts. In summary, the release plugin performs the following steps: Validate no local changes against your SCM Validate that there are no SNAPSHOT dependencies Convert the modules to the to-be released version Ensure the build and Unit/Integration tests succeed Commit the changes to SCM, then [...]]]></description>
				<content:encoded><![CDATA[<p><a href="http://blogs.sonatype.com/people/wp-content/uploads/2009/01/maven.png"><img class="alignright size-full wp-image-1488" title="maven" src="http://blogs.sonatype.com/people/wp-content/uploads/2009/01/maven.png" alt="" width="180" height="77" /></a>The Maven Release plugin enforces best practices for releasing Maven artifacts. In summary, the release plugin performs the following steps:</p>

<ol>
    <li>Validate no local changes against your SCM</li>
    <li>Validate that there are no SNAPSHOT dependencies</li>
    <li>Convert the modules to the to-be released version</li>
    <li>Ensure the build and Unit/Integration tests succeed</li>
    <li>Commit the changes to SCM, then Tag the release</li>
    <li>Checkout the tag to a clean location and build/deploy the artifacts</li>
</ol>

<p>Dealing with failures on Step #2 is where I want to focus today.
<span id="more-1486"></span></p>

<h2>Background</h2>

<p>Lets step back a moment and give some background on SNAPSHOTS. In Maven, all artifacts must have unique coordinates comprised of Group, Artifact, Version (there are a few more like classifier and type that aren&#8217;t relevant for this discussion&#8230; <a href="http://www.sonatype.com/book">see the free maven book</a> for more info on these.)</p>

<p>By definition artifacts are either Releases or SNAPSHOTS. Releases are expected to be immutable and SNAPSHOTS are temporal. A SNAPSHOT version has the SNAPSHOT keyword in the version string like 1.0-SNAPSHOT. When these artifacts are deployed to a remote repository, the SNAPSHOT portion is transformed into a time-stamp (in UTC) and an incremental build number is appended. Thus 1.0-SNAPSHOT becomes something like 1.0-20090105.231034-52 when it&#8217;s deployed.</p>

<h2>The Problem</h2>

<p>The reason you can&#8217;t release an artifact that depends on a SNAPSHOT is that later on, this artifact may change or simply may not be available. (Remember, SNAPSHOTS are temporal)</p>

<p>If you are attempting to perform a release and you have dependencies on 3rd party SNAPSHOT artifacts, you will need to resolve this before moving on. The first thing you might try is revert back to the previous release, leading to Best Practices #1 and 2:</p>

<h4>Rule #1: Only use 3rd party SNAPSHOTS when absolutely necessary</h4>

<p>Use SNAPSHOTs temporarily to validate fixes but don&#8217;t commit your poms this way unless&#8230;</p>

<h4>Rule #2: If you do need it, record why you need it</h4>

<p>Preferably as a comment in the Pom, referring to a bug number.
Adherence to this rule will make it easy to determine if you actually need the new dependency. It will also make it easy to decide if you can work around it or could live without it.</p>

<p>Assuming you really do need it, you have a couple of choices. The first is to request a release of the artifact. Chances are though if you are at this stage of a release, it&#8217;s too late to wait.</p>

<p>The obvious alternative is to control your own destiny and release anyway.</p>

<h2>Not the solution</h2>

<p>A common anti-pattern is to find the exact time-stamp-build number of the SNAPSHOT you are depending on and put that as your dependency version. We refer to this as locking to a timestamp.</p>

<h4>Rule #3 Never release using the Time-Stamped snapshot</h4>

<p>There are several reasons why this is a bad idea.</p>

<ol>
    <li> First is that Maven and Maven Tools that mimic Maven properly are able to detect a SNAPSHOT based on the timestamp pattern. (See my <a href="http://blogs.sonatype.com/people/2008/05/maven-code-how-to-detect-if-you-have-a-snapshot-version/">previous</a> entry showing how this is done correctly.) The release plugin will still fail if you do this because it correctly understands you have SNAPSHOT dependencies. The plugin has a flag to allow bypass this check and people unfortunately use it far too often.</li>
    <li>Since Maven and related tools see these time-stamped artifacts as a SNAPSHOT, you will have to keep this artifact in a SNAPSHOT repository. This might be acceptable if you take that artifact and host it in your repository manager but you must remember to never delete it. This would be complicated if you wanted to share your release with people outside your organization.</li>
    <li>The dependency could disappear from the external repository. If you aren&#8217;t using a repo manager (What? Didn&#8217;t you get the <a href="http://blogs.sonatype.com/people/2008/11/nine-reasons-to-use-a-repository-manager-sonatype-nexus/">memo</a>?) then you are totally subject to the cleanup process of the external repository.Not a good place to be.</li>
</ol>

<h2>The Solution</h2>

<p>There are a few approaches to this that are acceptable. Which one you choose depends on your level  of paranoia. This process can be recursive if your SNAPSHOT dependency has other SNAPSHOT dependencies. They are all approaches to rule #4:</p>

<h4>Rule #4: Convert the SNAPSHOT version to a Release version and host it in your repository</h4>

<ul>
    <li><strong>Just deploy the artifact:</strong> The simplest approach to this is to take the SNAPSHOT binary artifact itself and deploy it to your repository. Remember to adjust the Pom.xml as needed. If you use <a href="http://nexus.sonatype.org">Nexus</a>, then you can upload via the UI and the artifact will be renamed based on the version you choose. (others can upload via the ui, but I&#8217;m not sure if they rename the file for you) If you use this approach, be aware that the artifacts produced by Maven have a MANIFEST that contains the SNAPSHOT version. Maven 3.x uses this for plugins and may refuse to use this artifact based on the version not matching what was expected. The trouble with this approach is that should you need to patch this artifact down the road, you don&#8217;t know exactly what sources produced it.</li>
    <li><strong>Build from the sources:</strong> The next approach (and this is my preferred method) is to checkout the sources and build the snapshot yourself. This way I know exactly what I have should I need to patch it later. If you are uber-paranoyed you can commit the source to your scm for posterity. If you trust the remote SCM (as I do for the Apache projects) then simply recording the scm revision used to retrieve the source is enough. You&#8217;ll need to change the versions of the artifacts in the POMS and then deploy it to your repository. I like to put the svn revision right into the artifact version such as 1.0-[my company name]-[svnid]. <a href="http://repository.sonatype.org/content/repositories/sonatype-apache-releases/org/apache/maven/maven-core/">Look at an example</a> of how we did this this for 2.1-SNAPSHOTS of Maven code used by <a href="http://nexus.sonatype.org">Nexus</a> and <a href="http://m2eclipse.sonatype.org">M2eclipse</a>.</li>
</ul>

<h4>Rule #5: Change only the version, not the groupId or ArtifactId</h4>

<p>When you make these new versions, resist the urge to change the groupid as well since this will change the coordinates and Maven wouldn&#8217;t detect collisions. You could end up with your copy and the official copy of the same dependencies in your build. Having changed only the version makes it much easier to switch back to the official public release when it becomes available.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sonatype.com/people/2009/01/best-practices-for-releasing-with-3rd-party-snapshot-dependencies/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Maven code: How to detect if you have a SNAPSHOT version</title>
		<link>http://blog.sonatype.com/people/2008/05/maven-code-how-to-detect-if-you-have-a-snapshot-version/</link>
		<comments>http://blog.sonatype.com/people/2008/05/maven-code-how-to-detect-if-you-have-a-snapshot-version/#comments</comments>
		<pubDate>Thu, 29 May 2008 16:13:17 +0000</pubDate>
		<dc:creator>Brian Fox</dc:creator>
				<category><![CDATA[How-To]]></category>
		<category><![CDATA[Maven]]></category>
		<category><![CDATA[best practice]]></category>
		<category><![CDATA[snapshot]]></category>

		<guid isPermaLink="false">http://blogs.sonatype.com/people/brian/?p=88</guid>
		<description><![CDATA[I answer this question often enough that I decided to burn it to a blog so I don&#8217;t have to dig it out of the source anymore&#8230;and maybe save someone else the time along the way. Here is the relevant code that Maven uses to determine if an artifact is a snapshot or not: String [...]]]></description>
				<content:encoded><![CDATA[<p>I answer this question often enough that I decided to burn it to a blog so I don&#8217;t have to dig it out of the source anymore&#8230;and maybe save someone else the time along the way.</p>

<p>Here is the relevant code that Maven uses to determine if an artifact is a snapshot or not:
<span id="more-618"></span></p>

<p style="font-size:small"></p>

<pre><span style="font-family: arial;">String LATEST_VERSION = "LATEST";
String SNAPSHOT_VERSION = "SNAPSHOT";
Pattern VERSION_FILE_PATTERN = Pattern.compile(
 "^(.*)-([0-9]{8}.[0-9]{6})-([0-9]+)$" );
public boolean isSnapshot()
{
     if ( version != null || baseVersion != null )
     {
       Matcher m = VERSION_FILE_PATTERN.matcher( getBaseVersion() );
       if ( m.matches() )
       {
          setBaseVersion( m.group( 1 ) + "-" + SNAPSHOT_VERSION );
          return true;
       }
       else
       {
         return getBaseVersion().endsWith( SNAPSHOT_VERSION ) ||
         getBaseVersion().equals( LATEST_VERSION );
       }
     }
     else
     {
       return false;
     }
  }
</span></pre>

<p>Essentially this regex ( regular expression ) is checking if the version ends with SNAPSHOT or if the pattern matches a timestamped version such as &#8220;2.0.10-20080415.233129-15&#8243;.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sonatype.com/people/2008/05/maven-code-how-to-detect-if-you-have-a-snapshot-version/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
