gradle的各个环境依赖jar包的同一个版本导致的严重后果

  1. 背景:我司的A项目(gradle)、B项目(maven),且公司无maven私服,jar包均放在gitlab的项目的package registry中

  2. A项目依赖B项目的api包,我的做法如下:

    1. B项目版本定义成1.0-SNAPSHOT版本,永远都是这个版本
    2. 在gitlab创建3个项目,分别是maven-dev、maven-stg、maven-prod
    3. 部署的时候,分别把B项目的dev、stg、prod的包deploy到maven-dev、maven-stg、maven-prod中去
  3. 我的默认想法是:A项目分别从3个仓库中拉取,但是事与愿违,我的A项目配置的仓库信息为:

    repositories {
        mavenCentral()
        maven { url 'https://repo.spring.io/milestone' }
        maven {
            url = "https://gitlab.com/api/v4/groups/xxx/-/packages/maven"
            credentials(HttpHeaderCredentials) {
                def credentials = getGitLabCredentials()
                name = credentials.type
                value = credentials.token
            }
            authentication {
                header(HttpHeaderAuthentication)
            }
        }
    }
    
  4. 上方的url其实是包含了我司的所有项目,因此我的dev、stg、prod仓库也被包含在其中

  5. 由于上一步的原因,A项目拉取B项目的依赖时,会从3个仓库中去拉取,而3个仓库的排序我是不清楚的(清楚也没用),会从第一个仓库拉取,我这里是prod。所以就导致了一个现象是:我改了B,deploy到dev之后,A拉取的永远是prod(第一个)的。

  6. 实际上就是A不会根据环境区拉取我的B的各个环境的包。这就是gradle坑爹的地方执意,maven就没这个问题。所以能不用gradle就不用吧。

  7. 解决办法:

    1. 在A项目中为B的不同环境配置不同的仓库,很麻烦
    2. B的在各个环境中的版本不一致
    3. 我选择改变版本
  8. 解决办法实操:

    1. 在B中定义3个<profile>来代表3个换进

      <profile>
          <id>dev</id>
          <activation>
              <activeByDefault>true</activeByDefault>
          </activation>
          <properties>
              <revision>1.0.0-SNAPSHOT</revision>
          </properties>
      </profile>
      <profile>
          <id>dev</id>
          <activation>
              <activeByDefault>true</activeByDefault>
          </activation>
          <properties>
              <revision>1.5.0-SNAPSHOT</revision>
          </properties>
      </profile>
      <profile>
          <id>dev</id>
          <activation>
              <activeByDefault>true</activeByDefault>
          </activation>
          <properties>
              <revision>2.0.0-SNAPSHOT</revision>
          </properties>
      </profile>
      
    2. 在A中根据3个环境使用不同的版本

  9. 我解决这个问题的思路:

    1. 发现B改动了,但是A中的包没动静,不变化,即便我把本地B包删了,拉取下来的依然是旧的版本,两天前的版本

    2. 反复试验都不行

    3. 我最先在dev、stg、prod中deploy了1.0-SNAPSHOT版本

    4. 后来我把B改为1.0.0-SNAPSHOT,增加了1位版本号,发现没问题了,我以为是版本号规则问题,实际上并不是(实际原因是stg/prod根本没有3位这个版本),所以每次B改动deploy,A立马就能拉取最新的,于是我认为是版本号码需要3位才行。但是这个理论问了下chatgpt,回答模棱两可,表示有可能。问了gemini回答很肯定,不是版本号太短的问题。曾几何时我依稀记得在哪里看过说2位版本号码会有问题,但是我内心也其实也不相信这个理论。

    5. 于是一步一步给gemini贴配置代码,他一步一步帮我分析,最终发现有2个包下有B包的metadata.xml信息,如下:

      MacBook-Pro modules-2 % find . -type f -name "maven-metadata.xml" -exec grep -l "b-api" {} \;
      ./resources-2.1/69/3ecf46f9d1b384fd9c9562420c6e5388dcbef1f9/maven-metadata.xml
      ./resources-2.1/69/ca93e6109fca15ef792aebcfb428e1eb4bcab438/maven-metadata.xml
      ./resources-2.1/69/a1310a8210427b69f2aba4155c69a4ff61e970bd/maven-metadata.xml
      ./resources-2.1/69/14eea55ff435b509135d19bf004df42c01b6faef/maven-metadata.xml
      ./resources-2.1/69/8805c4bf152b42b7bf332af1f418bbf886e79f61/maven-metadata.xml
      ./resources-2.1/49/41143eb420aef00487e7d7514868cc546edac6dc/maven-metadata.xml
      
    6. 挨个查看上面6个文件的内容,发现69,和49开头的,进一步分析,发现69开头的都是我刚刚不断deploy B包的metadata信息,而49那个就是我观察日志拉取下来的旧包的信息

    7. gemini提说可能是我的api来自多个仓库,于是我依稀记得前两天创建3个环境的仓库的时候,分别deploy了一下试了一下是否可用,于是检查3个仓库,果然发现拉取的旧的就在我的prod那个仓库里面

    8. 此刻还没意识到是3个仓库的优先级问题,后面在提另外一个问题的时候灵光一闪,意识到了3个仓库的问题(这是根本原因)

    9. 于是就有了上方的解决方案。

posted @ 2025-11-27 21:27  神一样的存在  阅读(1)  评论(0)    收藏  举报