Difference between snapshot version and release version

In the process of using maven, we often have many public libraries in an unstable state during the development phase, which need to be modified and released at any time. It may be released once a day, and even N times a day when bugs are encountered. We know that maven's dependency management is based on version management. For the artifact in the release state, if the version number is the same, even if the components on our internal mirror server are newer than the local, maven will not actively download them. If we are doing dependency management based on the officially released version in the development stage, then when we encounter this problem, we need to upgrade the version number of the component, but this obviously does not meet the requirements and actual situation. However, if it is based on the snapshot version, then the problem is solved spontaneously, and maven has prepared all this for us.

      There are two kinds of warehouses in maven, snapshot snapshot warehouse and release release warehouse. The snapshot repository is used to save unstable versions in the development process, and the official release repository is used to save stable releases. To define a component/module as a snapshot version, you only need to add -SNAPSHOT after the version number of the module in the pom file (note that it must be capitalized here), as follows:

  1. <groupId>cc.mzone</groupId>
  2. <artifactId>m1</artifactId>
  3. <version>0.1-SNAPSHOT</version>
  4. <packaging>jar</packaging>

      maven2 will judge whether it is a snapshot version or an official version according to whether the version number of the module (version in the pom file) has -SNAPSHOT. If it is a snapshot version, it will be automatically published to the snapshot repository when mvn deploy, which will overwrite the old snapshot version, and when using the snapshot version of the module, without changing the version number, when compiling and packaging directly, maven will Automatically download the latest snapshot version from the mirror server. If it is an official release version, it will be automatically released to the official version library when mvn deploy, and using the official version of the module, without changing the version number, if the module of this version already exists locally when compiling and packaging, it will not be Actively go to the mirror server to download .

      Therefore, in the development phase, we can set the version of the public library as the snapshot version, and the dependent components refer to the snapshot version for development. After the snapshot version of the public library is updated, we do not need to modify the pom file to prompt the version number to download In the new version, you can re-download the latest snapshot library by directly executing the relevant compilation and packaging commands in mvn, which also facilitates our development.

 

At present, in the JAVA world, maven has become the de facto construction standard. The management and construction of many open source libraries are also based on maven. The learning curve of maven itself is relatively steep. Following the concept of "convention over configuration", maven has many conventions. This time I will first describe the choice of the definition of the version, SNAPSHOT or RELEASE?

version war

In the maven convention, the versions of dependencies are divided into two categories - SNAPSHOT and RELEASE. SNAPSHOT dependencies generally refer to version numbers ending with -SNAPSHOT, such as 1.0.1-SNAPSHOT. In addition, all version numbers that do not end with -SNAPSHOT are considered to be RELEASE versions, that is, official versions. Although there will be beta and rc versions, these are only beta versions from a software engineering perspective. For maven, These are the RELEASE versions. Now that Maven provides these two types of version numbers, what are their advantages and disadvantages before? In what scenarios are they used?

Interpreting SNAPSHOT

The dependencies of the same SNAPSHOT version can be deployed to the warehouse multiple times, that is to say, the dependencies of the same SNAPSHOT version can exist in the warehouse in multiple copies, each of which is a snapshot of the code at a specific time, which is also Meaning of SNAPSHOT. SNAPSHOT is not a specific version, but a collection of a series of versions, in which HEAD always points to the latest snapshot, which is generally the latest version visible to the outside world. This gives the illusion that the new one covers the old one, thus making Clients that use SNAPSHOT dependencies can always get the latest code by rebuilding (sometimes with -U to force an update). For example: A-->B-1.3.8-SNAPSHOT (understood that A depends on the 1.3.8-SNAPSHOT version of B), then after B-1.3.8-SNAPSHOT is updated and re-deployed to the warehouse, A only needs to rebuild You can get the latest code without changing the version of dependency B. It can be seen that this achieves the transparency of change communication, which is self-evident to help team collaboration in the development process.

Death of SNAPSHOT

The dependency of the SNAPSHOT version is appreciated and even "spoiled" because of the advantages of transparency in the communication of changes. Many teams simply use SNAPSHOT directly in the production environment, which is very convenient for the changes to take effect directly. However, as technicians, we should take the transparency of change communication very seriously. Change means risk, and transparency completely hides the risk. The existence of such a phenomenon in the production environment is even more frightening. For example: A-->B.1.0.3-SNAPSHOT, B adjusts a function implementation used by A and publishes it directly to the warehouse. A's rebuild may fail, or even worse, the build is successful and the runtime is abnormal. At this time, A suddenly fails even without code changes at all, which will bring more confusion.

这也是maven经常遭人诟病的一个因素,对于同一份代码,构建结果却不具备确定性,让很多人沮丧。当然这个不完全是因为依赖的问题,也有maven插件的问题,maven之前的版本寻找插件策略的方式也存在不确定性,maven在版本2的时候,会去寻找最新的插件版本(如果没配置的话)来执行构建,经常会找到SNAPSHOT版本的插件,所以依赖了一个不稳定的插件来执行构建,不确定性就大大增加。不过maven在3版本就改变了这个策略,会寻找最新稳定版的插件来执行构建,使得构建具备了确定性,稳定性也好多了。说明maven本身也在SNAPSHOT的问题上狠狠摔了一跤。

归根到底,这些问题的根源就是SNAPSHOT是变化的,是不稳定的,而应用(软件)依赖于变化并且不稳定的SNAPSHOT的依赖会导致自身也在变化和不稳定中,这是稳定性的一个大忌,依赖不稳定的服务或者依赖,上述的maven2的问题就是一个典型反例。

RELEASE简介

RELEASE版本和SNAPSHOT是相对的,非SANPSHOT版本即RELEASE版本,RELEASE版本是一个稳定的版本号,看清楚咯,是一个,不是一系列,可以认为RELEASE版本是不可变化的,一旦发布,即永远不会变化。

虽然RELEASE版本是稳定不变的,但是仓库还是有策略让这个原则变得可配置,有的仓库会配置成redeploy覆盖,这样RELEASE版本就变成SNAPSHOT了,伪装成RELEASE的SNAPSHOT,会让问题更费解和棘手,我一般称这类人为“挖坑专家”。

记住,RELEASE一旦发布,就不可改变。

如何选择

那么什么时候使用SNAPSHOT?什么时候使用RELEASE?这个可以从他们各自的特性上来看,SNAPSHOT版本的库是一直在变化的,或者说随时都会变化的,这样虽然可以获取到最新的特性,但是也存在不稳定因素,依赖一个不稳定的模块或者库会让模块自身也变得不稳定,尤其是自身对被依赖模块的变化超出掌控的情况。即使可以掌控被依赖模块的变化,也会带来不稳定的因素,因为每次变更都有引入bug的可能性。如果这么说,那么我们是不是要摒弃SANPSHOT了呢?答案肯定是否定的。

想象下,什么情况下,模块会一直变化或者变化比较剧烈?开发新特性的时候,所以对于团队之间协同开发的时候,模块之间出现依赖,变化会非常剧烈,如模块A依赖模块B,模块A必然需要最方便地获取模块B的特性,在开发期间,方便性比稳定性更重要。可以反证下,假设模块B使用RELEASE版本1.0.0,模块A依赖1.0.0,现在模块A出现了bug,需要修复下,那么A就要提供一个版本号1.0.1,这样所有依赖A模块都需要更新版本号,因为开发期间这种事情是如此多,所以会带来巨变。反观SNAPSHOT方案,如果模块B的版本是1.0.0-SNAPSHOT,模块A完全不需要修改版本号即可获取模块B的新特性。当开发进入预发布阶段,为了生产环境的稳定性,依赖应该是RELEASE版本,因为此时SNAPSHOT版本的模块自动获取新特性的特点恰恰会造成生产环境的不稳定性,生产环境上,稳定性重于一切。

魔幻之手

现在已经很明确了,在开发期间,活跃模块的版本号使用SNAPSHOT,在生产期间,依赖RELEASE版本模块。貌似,我们找到了银弹,不过这个只是理想状态,即所有的模块的版本都在自己的掌控或者间接掌控下,只有这样你才能影响对应模块的版本号。往往是理想很丰满,现实却很骨感,如果你依赖的一个模块只有SNAPSHOT版本,并且该模块也很活跃,最无助的是模块的维护人不理会你的请求,那么是否就没辙了,只能把应用构建在不稳定模块上呢?介绍一款maven插件——versions,这是一个非常强大的版本管理插件,其中有个对依赖版本加锁的特性——lock-snapshots,并且提供了参数可以控制锁定的依赖,就可以实现对特定的SNAPSHOT模块锁定版本,执行的命令如下:mvn versions:lock-snapshots -DincludesList="groupId:artifactId:type:classifier:version",执行这个命令之后,对应的版本号会变化,比如1.0.0-SNAPSHOT会变成1.0.0.20090327.172306-4,即完成了锁定,此时这个SNAPSHOT就变成了固定小版本的稳定版本,不会在变化了,也相当于正式版的功能了。当然以后也可以解锁,详细请看对应文档。

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324605761&siteId=291194637