Maven会下载一个新的快照JAR来取代在同一版本中刚刚创建的JAR吗?

azpvetkf  于 2022-10-26  发布在  Maven
关注(0)|答案(4)|浏览(189)

让我们假设我们的构建是关于从A到Z构建模块。这些项目的pom文件中的所有Version元素都被设置为-SNAPSHOT。
当我们构建POM文件时,Maven从项目A开始,然后转到B,最后到达项目Z。如果Z依赖于A,Maven是否检查远程repo以获得最新的A-SNAPSHOT.jar,并可能替换刚刚在A/Target/和/或本地Maven repo中创建的A-SNAPSHOT.jar
我认为-o可以避免上述情况,但我只是想了解一下。
是否可以将-o设置为特定的groupID,以避免在上述场景中可能发生的模糊错误。
是否可以将构建配置为下载本地repo中不可用的任何构件,但不替换现有构件。

e4yzc0pl

e4yzc0pl1#

不,React堆中的项目将始终优先于其他依赖项。
即使在下列情况下,这也是正确的:

  • 在设置了-U标志的情况下运行Maven,这意味着强制执行更新检查。
  • settings.xml或POM中将<updatePolicy>设置为always
  • install插件配置为<installAtEnd>true</installAtEnd>

Maven将找出哪些构件是您的React器的一部分,并将它们排除在更新检查之外。
这一点很容易证明。如果您尝试使用上面的任何一种配置运行Maven,您将看到Maven不会下载构件A(例如),因为每次下载都记录在控制台中。
例如,让我们假设您有这个根POM:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.example</groupId>
  <artifactId>root</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>pom</packaging>
  <name>root</name>
  <modules>
    <module>A</module>
    <module>B</module>
    ...
    <module>Z</module>
  </modules>
</project>

每个模块看起来如下所示:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>org.example</groupId>
    <artifactId>root</artifactId>
    <version>1.0-SNAPSHOT</version>
  </parent>
  <name>...</name>
  <artifactId>...</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>
</project>

但最后一个看起来像这样:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>org.example</groupId>
    <artifactId>root</artifactId>
    <version>1.0-SNAPSHOT</version>
  </parent>
  <artifactId>Z</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>
  <name>Z</name>
  <dependencies>
    <dependency>
      <groupId>org.example</groupId>
      <artifactId>A</artifactId>
      <version>${project.version}</version>
    </dependency>
  </dependencies>
</project>

那么,模块A将永远不会被来自存储库中的构件的另一个版本替换。

wz3gfoph

wz3gfoph2#

确认Daniel答案,实现代码在Maven2和Maven3之间有很大变化,但基本原理如下:

  • 当一个项目(模块)构建完成时,它的构件被附加到“构建React堆”,并被标记为“已解析”,
  • 当项目需要人工制品时,它会在React堆中寻找已解决的人工制品,
  • 如果未找到附加的已解析人工产物,则它将请求查看本地和远程存储库的解析。

因为只有在没有找到已解析的构件并且模块构建将其构件附加到被标记为已解析的React器时才进行解析,所以答案是:不,Maven不会下载新的快照JAR来替换刚刚在同一构建中创建的JAR。
您可以查看以下代码:MavenProjectDefaultArtifactResolverDefaultArtifactResolver

disbfnqx

disbfnqx3#

answer到另一个question的一部分可以解决您的问题:
当您构建应用程序时,Maven将在本地存储库中搜索依赖项。如果在那里找不到稳定的版本,它将搜索远程存储库(在settings.xml或pom.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构建,Maven将不会检查存储库是否有较新的版本。
请注意,此每日检查是默认行为。可以使用snapshot元素中定义的updatePolicy元素来自定义此行为。
从文档中:

更新策略

下载更新的频率-可以是“Always”、“Daily”(默认)、“Interval:xxx”(以分钟为单位)或“Never”(只有在本地不存在的情况下)。
多亏了朱利安·卡西克的精确度。

jmp7cifd

jmp7cifd4#

据我所知,如果可用的话,最好使用本地存储库中的快照构建。为了证明这一点,
1.将本地maven存储库移动到其他位置,保留.m2/repository目录为空。(不要删除它,因为以后可能找不到某些构件。远程存储库确实关闭:))
1.更改Z使用的A中的接口
1.运行生成。如果我的思路是正确的,它在构建Z时应该失败。您没有更改远程构件,并且存储库没有任何东西(因为您在上面的步骤中移动了它)。
1.如果需要,请恢复原始存储库文件夹
1.回滚A中的接口变化。

相关问题