Why do a lot of Maven dependency versions end with SNAPSHOT? - java

Is there any special meaning for snapshot in the Maven version?

Yes
SNAPSHOT - means it's not the final version. The code is still being developed and the artifact is not released. It may have bugs.
From: http://maven.apache.org/guides/getting-started/index.html
version This element indicates the version of the artifact generated by the project. Maven goes a long way to help you with version management and you will often see the SNAPSHOT designator in a version, which indicates that a project is in a state of development. We will discuss the use of snapshots and how they work further on in this guide.
This has even long article: http://sonatype.com/books/maven-book/reference/pom-relationships-sect-pom-syntax.html see under 3.3.1.2. SNAPSHOT Versions headline
Why would you use this? SNAPSHOT versions are used for projects under active development. If your project depends on a software component that is under active development, you can depend on a SNAPSHOT release, and Maven will periodically attempt to download the latest snapshot from a repository when you run a build. Similarly, if the next release of your system is going to have a version "1.4", your project would have a version "1.4-SNAPSHOT" until it was formally released.

Any project version with SNAPSHOT in it means that its a development build, not a release, and is usually built off of whatever's the newest commit in the repository.
This means they are not stable since someone could commit broken code, broken project gets built, and sometime later you update to the newest build which is broken.

Related

What is maven release plugin and what does github to do with it?

What exactly is maven release plugin? What is its purpose? I found it in the middle of a tutorial but don't understand what it is useful for. Also, the teacher is showing us how to create tags on GitHub. What do the maven release plugin and GitHub have in common?
Fundamentally, "releasing a project" means that you have a version of your project that is stable and that you wish to release to the public ("publishing" could be a good synonym).
The maven release plugin helps you with several tasks that need to be done in order to release a project:
Make sure that the project uses no SNAPSHOT-dependencies (as SNAPSHOT-dependencies are considered unreleased and thus not necessarily stable)
Create a tag in your source control management system (in your case GitHub) so that you can come back to the released version e. g. if you need to fix a bug in an older release
Remove the -SNAPSHOT suffix from the project version in your pom.xml
Build the project
Deploy the project to your release repository (usually Maven Central).
Bump the version string in your pom.xml and add -SNAPSHOT again
Note that you can do all of these steps manually (e. g. you can simply edit your pom.xml and remove the -SNAPSHOT suffix and then run mvn deploy to deploy the project to Maven Central), but the release plugin helps with that as it automates those tasks and makes sure that you don't forget anything.
To answer what GitHub has to do with it: Again, the release plugin automatically creates a tag in your SCM so-that you can check it out some time later if you need to. It does not matter what your SCM is, it can be GitHub, Bitbucket, GitLab or whatever else. It's just that most people use GitHub as their SCM host.

Is it best practise to store snapshot versions in Artifactory in maven applications?

Is it best practise to store snapshot versions in Artifactory in maven applications?
As snapshot versions should be used only for development purposes.
It's not true that SNAPSHOT versions should be used only for development. When SNAPSHOT version is uploaded it's not uploaded as is - it gets transformed into a unique version, something like this: 1-20150904.140213-59. When referencing such dependency you can:
either use SNAPSHOT word like 1-SNAPSHOT, then you don't really know which exact version is used
or use a resolved version: 1-20150904.140213-59
Using the 1st option is discouraged for any purpose - be it a deployment, or a <dependency> in pom.xml (even for development purposes), because it leads to non-repeatable actions. You run build once - you get a dependency with version 1-20150904.140213-59 downloaded, you run it for the 2nd time you may get another version like 1-20150904.140214-60.
But there's nothing wrong with referencing the full (resolved) version. So you can leverage snapshots the same way you do with release versions. Note though that remote repositories (e.g. Nexus) can be configured to delete old snapshot versions - so you need to take this into consideration.
By the way, snapshots are very convenient for releases.
A SNAPSHOT version is meant to be used for development. You can store it in Artifactory, but for using an artifact productively, you should build a release version.
#Stanislav is right that timestamped SNAPSHOTs could technically be used like release versions, and I believe him that this works, but I wouldn't do it because it is not how SNAPSHOTs and releases were meant to be.

Removing a Version from a Maven Remote Repo

I have currently been working on my first Maven project and have run into some confusion with Maven versioning. I understand that while developing a new version the SNAPSHOT keyword should be used in the version number. I also understand that a non SNAPSHOT version should only be released once.
I was wondering if it were possible to delete an old version from a Maven remote repository. For example, if I don't version want 1.0.2 downloadable anymore, what should I do?
Additionally, Let's say I am working on version 1.0-SNAPSHOT. When I deploy version 1.0, will the last 1.0-SNAPSHOT version be deleted/replaced by its non SNAPSHOT counterpart?
Simple answer to this: A release version (without SNAPSHOT) is immutable. This includes it will be kept forever.
The reason is:
If someone uses your version 1.0.2 and you simply can delete it those > builds will fail without an obvious reason.
One word about the thing you mentioned:
I also understand that a non SNAPSHOT version should only be released once.
You can not release the same version twice. Never possible and should never. This would mean you would override and existing version which changes behaviour. This could also break other builds.
You can take a look at for example https://search.maven.org/artifact/javax.mail/mail you will find artifacts which are more than fifteen years old. They will never deleted cause It could be the case that someone is using them.
If you have an issue in your version 1.0.2 just simply create a new version 1.0.3 which fixes the issues. The version number should follow semantical versioning.
If you are running a version 1.0-SNAPSHOT during development and making a release of it (usually via maven-release-plugin) during the release of 1.0 usually the 1.0-SNAPSHOT versions will be automatically deleted. So the 1.0-SNAPSHOT is no longer available. This is the default configuration for maven repository managers.
If you use AWS S3 bucket as maven repository there is a brutal workaround. I've tested it and it works.
You can simply delete release folder eg 1.0.0/ on remote repository. Fact, it leaves some legacy version tag in main maven-metadata.xml but it will be overwritten when you perform next release of this version.

Maven dependency download not checking change [duplicate]

I am a bit confused about the meaning of a Maven Snapshot and why we build one?
A snapshot version in Maven is one that has not been released.
The idea is that before a 1.0 release (or any other release) is done, there exists a 1.0-SNAPSHOT. That version is what might become 1.0. It's basically "1.0 under development". This might be close to a real 1.0 release, or pretty far (right after the 0.9 release, for example).
The difference between a "real" version and a snapshot version is that snapshots might get updates. That means that downloading 1.0-SNAPSHOT today might give a different file than downloading it yesterday or tomorrow.
Usually, snapshot dependencies should only exist during development and no released version (i.e. no non-snapshot) should have a dependency on a snapshot version.
The three others answers provide you a good vision of what a -SNAPSHOT version is. I just wanted to add some information regarding the behavior of Maven when it finds a SNAPSHOT dependency.
When you build an application, Maven will search for dependencies in the local repository. If a stable version is not found there, it will search the remote repositories (defined in settings.xml or pom.xml) to retrieve this dependency. Then, it will copy it into the local repository, to make it available for the next builds.
For example, a foo-1.0.jar library is considered as a stable version, and if Maven finds it in the local repository, it will use this one for the current build.
Now, if you need a foo-1.0-SNAPSHOT.jar library, Maven will know that this version is not stable and is subject to changes. That's why Maven will try to find a newer version in the remote repositories, even if a version of this library is found on the local repository. However, this check is made only once per day. That means that if you have a foo-1.0-20110506.110000-1.jar (i.e. this library has been generated on 2011/05/06 at 11:00:00) in your local repository, and if you run the Maven build again the same day, Maven will not check the repositories for a newer version.
Maven provides you a way to change this update policy in your repository definition:
<repository>
<id>foo-repository</id>
<url>...</url>
<snapshots>
<enabled>true</enabled>
<updatePolicy>XXX</updatePolicy>
</snapshots>
</repository>
where XXX can be:
always: Maven will check for a newer version on every build;
daily, the default value;
interval:XXX: an interval in minutes (XXX)
never: Maven will never try to retrieve another version. It will do that only if it doesn't exist locally. With the configuration, SNAPSHOT version will be handled as the stable libraries.
(model of the settings.xml can be found here)
The "SNAPSHOT" term means that the build is a snapshot of your code at a given time.
It usually means that this version is still under heavy development.
When the code is ready and it is time to release it, you will want to change the version listed in the POM. Then instead of having a "SNAPSHOT" you would use a label like "1.0".
For some help with versioning, check out the Semantic Versioning specification.
A "release" is the final build for a version which does not change.
A "snapshot" is a build which can be replaced by another build which has the same name. It implies that the build could change at any time and is still under active development.
You have different artifacts for different builds based on the same code. E.g. you might have one with debugging and one without. One for Java 5.0 and one for Java 6. Generally its simpler to have one build which does everything you need. ;)
Maven versions can contain a string literal "SNAPSHOT" to signify that a project is currently under active development.
For example, if your project has a version of “1.0-SNAPSHOT” and you deploy this project’s artifacts to a Maven repository,
Maven would expand this version to “1.0-20080207-230803-1” if you were to
deploy a release at 11:08 PM on February 7th, 2008 UTC. In other words, when you
deploy a snapshot, you are not making a release of a software component; you are
releasing a snapshot of a component at a specific time.
So mainly snapshot versions are used for projects under active development.
If your project depends on a software component that is under active development,
you can depend on a snapshot release, and Maven will periodically attempt
to download the latest snapshot from a repository when you run a build. Similarly, if
the next release of your system is going to have a version “1.8,” your project would
have a “1.8-SNAPSHOT” version until it was formally released.
For example , the following dependency would always download the latest 1.8 development JAR of spring:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
<version>1.8-SNAPSHOT”</version>
</dependency>
Maven
An example of maven release process
I'd like to make a point about terminology. The other answers gave good explanations about what a "snapshot" version is in the context of Maven. But does it follow that a non-snapshot version should be termed a "release" version?
There is some tension between the semantic versioning idea of a "release" version, which would seem to be any version that does not have a qualifier such as -SNAPSHOT but also does not have a qualifier such as -beta.4; and Maven's idea idea of a "release" version, which only seems to include the absence of -SNAPSHOT.
In other words, there is a semantic ambiguity of whether "release" means "we can release it to Maven Central" or "the software is in its final release to the public". We could consider -beta.4 to be a "release" version if we release it to the public, but it's not a "final release". Semantic versioning clearly says that something like -beta.4 is a "pre-release" version, so it wouldn't make sense for it to be called a "release" version, even without -SNAPSHOT. In fact by definition even -rc.5 is a release candidate, not an actual release, even though we may allow public access for testing.
So Maven notwithstanding, in my opinion it seems more appropriate only to call a "release" version one that doesn't have any qualifier at all, not even -beta.4. Perhaps a better name for a Maven non-snapshot version would be a "stable" version (inspired by another answer). Thus we would have:
1.2.3-beta.4-SNAPSHOT: A snapshot version of a pre-release version.
1.2.3-SNAPSHOT: A snapshot version of a release version.
1.2.3-beta.4: A stable version of a pre-release version.
1.2.3: A release version (which is a stable, non-snapshot version, obviously).
usually in maven we have two types of builds
1)Snapshot builds
2)Release builds
snapshot builds:SNAPSHOT is the special version that indicate current deployment copy not like a regular version, maven checks the version for every build in the remote repository
so the snapshot builds are nothing but development builds.
Release builds:Release means removing the SNAPSHOT at the version for the build, these are the regular build versions.
A Maven SNAPSHOT is an artifact created by a Maven build and pretends to help developers in the software development cycle.
A SNAPSHOT is an artifact (or project build result ) that is not pretended to be used anywhere, it's only a temporarily .jar, ear, ... created to test the build process or to test new requirements that are not yet ready to go to a production environment.
After you are happy with the SNAPSHOT artifact quality, you can create a RELEASE artifact that can be used by other projects or can be deployed itself.
In your project, you can define a SNAPSHOT using the version element in the pom.xml file of Maven:
<groupId>example.project.maven</groupId>
<artifactId>MavenEclipseExample</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<description>Maven pom example</description>
If you want to understand better Maven you can look into these articles too:
https://connected2know.com/programming/menu-maven-articles/
This is how a snapshot looks like for a repository and in this case is not enabled, which means that the repository referred in here is stable and there's no need for updates.
<project>
...
<repositories>
<repository>
<id>lds-main</id>
<name>LDS Main Repo</name>
<url>http://code.lds.org/nexus/content/groups/main-repo</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
</project>
Another case would be for:
<snapshots>
<enabled>true</enabled>
</snapshots>
which means that Maven will look for updates for this repository. You can also specify an interval for the updates with tag.
simply snapshot means it is the version which is not stable one.
when version includes snapshot like 1.0.0 -SNAPSHOT means it is not stable version and look for remote repository to resolve dependencies
Snapshot simply means depending on your configuration Maven will check latest changes on a special dependency. Snapshot is unstable because it is under development but if on a special project needs to has a latest changes you must configure your dependency version to snapshot version. This scenario occurs in big organizations with multiple products that these products related to each other very closely.
understanding the context of SDLC will help understand the difference between snapshot and the release. During the dev process developers all contribute their features to a baseline branch. At some point the lead thinks enough features have accumulated then he will cut a release branch from the baseline branch. Any builds prior to this time point are snapshots. Builds post to this point are releases. Be noted, release builds could change too before going to production if any defect spot during the release testing.
As the name suggests, snapshot refers to a state of project and its dependencies at that moment of time. Whenever maven finds a newer SNAPSHOT of the project, it downloads and replaces the older .jar file of the project in the local repository.
Snapshot versions are used for projects under active development. If your project depends on a software component that is under active development, you can depend on a snapshot release, and Maven will periodically attempt to download the latest snapshot from a repository when you run a build.
In development phase Maven snapshots everyday looks for newer higher version if available in nexus repository n download it locally for next build.
Four option you can set in respository defination
Always,
Daily (default),
Interval,
Never,
Note: In production release we should not have dependency on snapshot version.
The SNAPSHOT value refers to the 'latest' code along a development branch and provides no guarantee the code is stable or unchanging. Conversely, the code in a 'release' version (any version value without the suffix SNAPSHOT) is unchanging.
In other words, a SNAPSHOT version is the 'development' version before the final 'release' version. The SNAPSHOT is "older" than its release.
During the release process, a version of x.y-SNAPSHOT changes to x.y. The release process also increments the development version to x.(y+1)-SNAPSHOT. For example, version 1.0-SNAPSHOT is released as version 1.0, and the new development version is version 1.1-SNAPSHOT.

Info needed on gradle release plugin as how maven provides release plugin

Can any one let me know if there is any release plugin provided by gradle to do similar tasks performed as Maven release plugin do? I know we can load the maven tasks in gradle but do not want to do it and keep things clean if there is any inbuilt plugin provided by gradle. If there is one please please post sample config or code. Thanks in advance.
In maven we have the following tasks performed by maven release plugin:
release:clean Clean up after a release preparation.
release:prepare Prepare for a release in SCM.
release:prepare-with-pom Prepare for a release in SCM, and generate release POMs that record the fully resolved projects used.
release:rollback Rollback a previous release.
release:perform Perform a release from SCM.
release:stage Perform a release from SCM into a staging folder/repository.
release:branch Create a branch of the current project with all versions updated.
release:update-versions Update the versions in the POM(s).
Thanks
Nithin
Right there are so many choices. I tested most of the release plugins and wrote couple of them for different clients on my own. I really recommend the nebula-release plugin (https://plugins.gradle.org/plugin/nebula.nebula-release). This is driven by the netflix guys, well documented, well maintained and supports all kind of use cases and customizations.
For what its worth, I have recently published a gradle-release-plugin of my own (https://github.com/anshulverma/gradle-release-plugin).
It works on convention rather than configuration. Which is why I built it in the first place. Most of the time we all want the same thing -- semantic versioning with ability to snapshot and tag commits along with publish ability to OSS and bintray repositories. This is what this plugin provides and takes care of most of the configuration.
It is in active development at the moment. Feel free to open issues if any advancements come to mind.
I have been using mentioned townsfolk's release plugin, but it is not actively developed anymore with a few open issues (update: It seems that Daniel Tschinder took over development of that plugin, so probably there will be newer versions).
Recently I have found Axion release plugin which doesn't use separate file to keep current version, but uses Git commits and tags to determine it. It simplifies releasing process and fits in Continuous Delivery trend. What is also very important the author is very responsible.
In addition to the README file nice description can be found on their blog.
Axion itself do only versioning tests from your list, but it can be used together with maven-publish, bintray or any other publishing plugin to push artifacts into remote artifacts repository.
As far as I can tell, there are 4 release plugins right now.
https://github.com/townsfolk/gradle-release
https://github.com/ari/gradle-release-plugin
https://github.com/stianh/gradle-release-plugin
https://github.com/anshulverma/gradle-release-plugin
The townsfolk plugin is the one that works the most like the maven plugin and it works quite well so far ... but is currently not maintained (see github). The other 2 plugins work much differently from the maven release plugin (and pretty similarly to each other). These other two plugins use version control (svn/git) to keep track of version numbers instead of burying (and updating) version numbers in the build.gradle file.
You can also find various approaches here: https://bitbucket.org/evgenyg/demo-releases-plugin/src/master/build.gradle
And some nice slides here: http://www.slideshare.net/evgenyg/release-it
Hope this helps!

Categories

Resources