关于java:Maven Snapshot究竟是什么?我们为什么需要它?

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

我对Maven快照的含义有点困惑,为什么要构建一个快照?


Maven中的快照版本尚未发布。

其思想是,在执行1.0版本(或任何其他版本)之前,存在一个1.0-SNAPSHOT。这个版本可能会成为1.0。基本上是"1.0在开发中"。这可能接近真实的1.0版本,或者相当远(例如,在0.9版本之后)。

"真实"版本和快照版本的区别在于快照可能会得到更新。这意味着今天下载1.0-SNAPSHOT可能会提供与昨天或明天下载不同的文件。

通常,快照依赖项只应在开发过程中存在,并且没有发布版本(即没有非快照)应依赖于快照版本。


其他三个答案为您提供了一个很好的-SNAPSHOT版本的愿景。我只是想添加一些关于maven行为的信息,当它发现SNAPSHOT依赖时。

构建应用程序时,Maven将在本地存储库中搜索依赖项。如果在那里找不到稳定版本,它将搜索远程存储库(在settings.xmlpom.xml中定义)以检索此依赖项。然后,它将把它复制到本地存储库中,使其可用于下一个构建。

例如,一个foo-1.0.jar库被认为是一个稳定的版本,如果maven在本地存储库中找到它,它将使用这个版本进行当前的构建。

现在,如果您需要一个foo-1.0-SNAPSHOT.jar库,maven会知道这个版本不稳定,可能会有变化。这就是为什么Maven会尝试在远程存储库中查找较新版本,即使在本地存储库中找到了此库的版本。但是,这种检查每天只进行一次。这意味着,如果您在本地存储库中有一个foo-1.0-20110506.110000-1.jar(即,此库是在2011/05/06 11:00:00时生成的),并且如果您在同一天再次运行maven build,maven将不会检查存储库中的更新版本。

Maven为您提供了一种在存储库定义中更改此更新策略的方法:

1
2
3
4
5
6
7
8
<repository>
    <id>foo-repository</id>
    <url>...</url>
    <snapshots>
        <enabled>true</enabled>
        <updatePolicy>XXX</updatePolicy>
    </snapshots>
</repository>

其中,XXX可以是:

  • 总是:Maven会在每次构建时检查更新的版本;
  • 每日,默认值;
  • 间隔:xxx:以分钟为单位的间隔(xxx)
  • 从不:Maven永远不会尝试检索另一个版本。只有当它不存在于本地时,它才会这样做。通过配置,SNAPSHOT版本将作为稳定库处理。

(可在此处找到settings.xml的模型)


"快照"术语意味着构建是给定时间内代码的快照。

这通常意味着这个版本仍在大量开发中。

当代码准备好并且是时候发布它时,您将要更改POM中列出的版本。然后,您将使用类似"1.0"的标签,而不是"快照"。

有关版本控制的一些帮助,请查看语义版本控制规范。


"版本"是不更改版本的最终版本。

"快照"是一个生成,它可以被另一个同名的生成替换。这意味着构建可以随时更改,并且仍在积极开发中。

对于基于相同代码的不同构建,您有不同的工件。例如,您可能有一个带有调试功能,另一个没有调试功能。一个用于Java 5,一个用于Java 6。一般来说,拥有一个可以满足所有需要的构建会更简单。;)


Maven版本可以包含字符串"snapshot",表示项目当前处于活动开发状态。

例如,如果您的项目具有"1.0-Snapshot"版本,并且您将此项目的构件部署到Maven存储库中,如果你愿意的话,Maven会把这个版本扩展到"1.0-20080207-230803-1"在2008年2月7日(UTC)下午11:08部署发布。换句话说,当你部署快照,您不是在发布软件组件;您是在特定时间释放组件的快照。

所以快照版本主要用于正在开发的项目。如果您的项目依赖于正在进行活动开发的软件组件,您可以依赖快照版本,Maven将定期尝试运行生成时从存储库下载最新快照。同样,如果您的系统的下一个版本将有一个版本"1.8",您的项目将有一个"1.8快照"版本,直到正式发布。

例如,以下依赖项将始终下载最新的Spring 1.8开发jar:

1
2
3
4
5
    <dependency>
        <groupId>org.springframework</groupId>
        spring</artifactId>
        <version>1.8-SNAPSHOT"</version>
    </dependency>

马文

Maven发布过程示例

enter image description here


我想谈谈术语。其他的答案很好地解释了在Maven环境中什么是"快照"版本。但这是否意味着非快照版本应该称为"发布"版本?

"发布"版本的语义版本化概念与Maven的"发布"版本概念之间存在一定的张力,该版本似乎是没有限定符(如-SNAPSHOT)但也没有限定符(如-beta.4)的任何版本;而Maven的"发布"版本概念似乎只包括缺少-SNAPSHOT

换句话说,对于"发布"是指"我们可以将其发布到Maven Central"还是"软件正在向公众发布最终版本",存在语义上的歧义。如果我们向公众发布,我们可以将-beta.4视为"发布"版本,但它不是"最终发布"。语义版本化清楚地表明,像-beta.4这样的东西是一个"预发布"版本,所以即使没有-SNAPSHOT也不能称之为"发布"版本。事实上,根据定义,即使-rc.5是一个候选发布版本,而不是实际的发布版本,尽管我们可能允许公众访问进行测试。

尽管如此,Maven,在我看来,仅仅称之为"发布"版本更合适,它根本没有任何限定符,甚至没有-beta.4。也许Maven非快照版本的更好名称是"稳定"版本(受另一个答案的启发)。因此,我们将:

  • 1.2.3-beta.4-SNAPSHOT:预发布版本的快照版本。
  • 1.2.3-SNAPSHOT:发布版本的快照版本。
  • 1.2.3-beta.4:预发布版本的稳定版本。
  • 1.2.3:发布版本(显然是稳定的非快照版本)。


通常在Maven中,我们有两种类型的构建1)快照生成2)发布版本

  • 快照生成:快照是指示当前部署副本的特殊版本,与常规版本不同,Maven检查远程存储库中每个生成的版本。所以快照构建只是开发构建。

  • 发布版本:发布意味着删除版本中的快照,这些是常规的生成版本。


  • 这就是快照在存储库中的外观,在这种情况下,不启用快照,这意味着这里提到的存储库是稳定的,不需要更新。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    <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>

    另一种情况是:

    1
    2
    3
    <snapshots>
            <enabled>true</enabled>
    </snapshots>

    这意味着Maven将查找此存储库的更新。还可以为带有标记的更新指定间隔。


    简单的快照意味着它是一个不稳定的版本。

    当版本包含类似1.0.0的快照时-快照意味着它不是稳定的版本,并寻找远程存储库来解决依赖关系


    了解SDLC的上下文将有助于理解快照和发布之间的区别。在开发过程中,开发人员都将他们的特性贡献给基线分支。在某一点上,领导认为已经积累了足够的特性,然后他将从基线分支中削减一个发布分支。在此时间点之前的任何生成都是快照。发布到这一点的构建就是发布。需要注意的是,如果在发布测试期间出现任何缺陷,那么发布构建在投入生产之前也会发生变化。