You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

基于Sonatype Nexus优化Gradle多项目构建依赖的技术问询

我之前帮团队搞定过一模一样的场景,核心就是把原来的本地项目依赖改成制品仓库依赖,让每个子项目都能独立发布到Nexus,这样开发ProjectA的同学只需要拉取ProjectA代码,依赖直接从Nexus拿就行。下面给你一步步说具体操作:

1. 先给ProjectB、ProjectC配置Nexus发布能力

首先得让这两个依赖项目能打包上传到Nexus,咱们用Gradle官方的maven-publish插件来实现:

  • 在ProjectB和ProjectC的build.gradle里添加插件:

    plugins {
        id 'java'
        id 'maven-publish'
    }
    
  • 配置发布的制品元信息(groupId/artifactId/version要和团队规范统一,比如和包名对齐):

    publishing {
        publications {
            mavenJava(MavenPublication) {
                from components.java
                groupId = 'com.yourcompany.yourteam' // 替换成你的团队groupId
                artifactId = 'projectb' // ProjectC这里改成projectc
                version = '1.0.0-SNAPSHOT' // 开发阶段用快照版,正式发布时改成稳定版比如1.0.0
            }
        }
        repositories {
            maven {
                // 快照版上传到Nexus的快照仓库,正式版换成maven-releases地址
                url = uri("http://your-nexus-address/repository/maven-snapshots/")
                credentials {
                    // 用gradle.properties或环境变量存敏感信息,绝对不要硬编码!
                    username = project.findProperty('nexusUsername') ?: System.getenv('NEXUS_USERNAME')
                    password = project.findProperty('nexusPassword') ?: System.getenv('NEXUS_PASSWORD')
                }
            }
        }
    }
    
  • 在项目根目录的gradle.properties里添加Nexus账号密码:

    nexusUsername=your-nexus-login
    nexusPassword=your-nexus-password
    
  • 执行发布命令:在ProjectB/ProjectC根目录运行 ./gradlew publish,就能把编译好的jar上传到Nexus仓库了。

2. 修改ProjectA的依赖配置,从Nexus拉取依赖

现在让ProjectA彻底摆脱本地子项目依赖,转而从Nexus获取:

  • 首先修改ProjectA的settings.gradle,移除原来的include ':ProjectB'include ':ProjectC',这样Gradle就不会再去找本地的子项目目录了。

  • 在ProjectA的build.gradle里添加Nexus仓库地址,告诉Gradle去哪里找依赖:

    repositories {
        mavenCentral()
        // 快照仓库
        maven {
            url = uri("http://your-nexus-address/repository/maven-snapshots/")
            credentials {
                username = project.findProperty('nexusUsername') ?: System.getenv('NEXUS_USERNAME')
                password = project.findProperty('nexusPassword') ?: System.getenv('NEXUS_PASSWORD')
            }
        }
        // 如果需要拉取正式版依赖,再加release仓库
        maven {
            url = uri("http://your-nexus-address/repository/maven-releases/")
            credentials {
                username = project.findProperty('nexusUsername') ?: System.getenv('NEXUS_USERNAME')
                password = project.findProperty('nexusPassword') ?: System.getenv('NEXUS_PASSWORD')
            }
        }
    }
    
  • 把原来的本地项目依赖替换成Maven坐标依赖:

    dependencies {
        // 替换掉原来的 compile project(':ProjectB')
        implementation 'com.yourcompany.yourteam:projectb:1.0.0-SNAPSHOT'
        // 注:如果ProjectA是间接依赖ProjectC(通过ProjectB传递),不用单独声明;如果需要直接依赖再添加
        // implementation 'com.yourcompany.yourteam:projectc:1.0.0-SNAPSHOT'
    }
    
3. 实用优化技巧
  • 统一版本管理:用Gradle的Version Catalog来统一管理所有依赖版本,避免每个项目重复写版本号。在ProjectA的settings.gradle里配置:

    dependencyResolutionManagement {
        versionCatalogs {
            libs {
                version('projectb', '1.0.0-SNAPSHOT')
                version('projectc', '1.0.0-SNAPSHOT')
                library('projectb', 'com.yourcompany.yourteam', 'projectb').versionRef('projectb')
                library('projectc', 'com.yourcompany.yourteam', 'projectc').versionRef('projectc')
            }
        }
    }
    

    之后ProjectA的依赖可以写成 implementation libs.projectb,简洁又好维护。

  • 本地开发灵活切换:如果偶尔需要同时修改ProjectA和ProjectB,可以在ProjectA的settings.gradle加条件判断,当本地存在ProjectB目录时自动切换为本地依赖:

    def projectBDir = file('../ProjectB')
    if (projectBDir.exists()) {
        include ':ProjectB'
        project(':ProjectB').projectDir = projectBDir
    }
    

    不用改依赖声明就能无缝切换本地/仓库依赖。

  • 快照版实时更新:如果用SNAPSHOT版本,Gradle默认会缓存快照,可以配置强制每次构建拉最新版本:

    configurations.all {
        resolutionStrategy.cacheChangingModulesFor 0, 'seconds'
    }
    

内容的提问来源于stack exchange,提问作者PCL

火山引擎 最新活动