[java] What exactly is a Maven Snapshot and why do we need it?

I am a bit confused about the meaning of a Maven Snapshot and why we build one?

This question is related to java maven dependency-management

The answer is


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. ;)


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


usually in maven we have two types of builds 1)Snapshot builds 2)Release builds

  1. 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.

  2. Release builds:Release means removing the SNAPSHOT at the version for the build, these are the regular build versions.


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

enter image description here


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.


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)


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.


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.


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/


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.


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.


Snapshot Dependencies Snapshot dependencies are dependencies (JAR files) which are under development. Instead of constantly updating the version numbers to get the latest version, you can depend on a snapshot version of the project. Snapshot versions are always downloaded into your local repository for every build, even if a matching snapshot version is already located in your local repository. Always downloading the snapshot dependencies assures that you always have the latest version in your local repository, for every build.

your pom contains a lot of -SNAPSHOT dependencies and those -SNAPSHOT dependencies are a moving target enter image description here

enter image description here

https://dzone.com/articles/maven-release-plugin-in-the-enterprise https://javarevisited.blogspot.com/2019/03/top-5-course-to-learn-apache-maven-for.html https://www.mojohaus.org/versions-maven-plugin/examples/lock-snapshots.html http://tutorials.jenkov.com/maven/maven-tutorial.html


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).

Examples related to java

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How much should a function trust another function How to implement a simple scenario the OO way Two constructors How do I get some variable from another class in Java? this in equals method How to split a string in two and store it in a field How to do perspective fixing? String index out of range: 4 My eclipse won't open, i download the bundle pack it keeps saying error log

Examples related to maven

Maven dependencies are failing with a 501 error Why am I getting Unknown error in line 1 of pom.xml? Why am I getting "Received fatal alert: protocol_version" or "peer not authenticated" from Maven Central? How to resolve Unable to load authentication plugin 'caching_sha2_password' issue Unable to compile simple Java 10 / Java 11 project with Maven ERROR Source option 1.5 is no longer supported. Use 1.6 or later 'react-scripts' is not recognized as an internal or external command How to create a Java / Maven project that works in Visual Studio Code? "The POM for ... is missing, no dependency information available" even though it exists in Maven Repository Java.lang.NoClassDefFoundError: com/fasterxml/jackson/databind/exc/InvalidDefinitionException

Examples related to dependency-management

What's the difference between implementation and compile in Gradle? How to install a specific version of package using Composer? How to clear cache in Yarn? Javascript require() function giving ReferenceError: require is not defined How to add local .jar file dependency to build.gradle file? How to clean old dependencies from maven repositories? Android Studio: Add jar as library? Dealing with "Xerces hell" in Java/Maven? How do I add a Maven dependency in Eclipse? Force re-download of release dependency using Maven