Gradle打包生成dependencies.xml详解

在 Gradle 打包时生成 dependencies.xml 文件,可以通过创建一个自定义的 Gradle 任务来实现。该任务的核心是收集项目的依赖信息,并将其以 XML 格式写入文件。以下是两种主流方案:

方案一:使用内置的 dependencies 报告任务(推荐)

Gradle 内置了生成依赖报告的功能,我们可以配置一个自定义任务来生成 XML 格式的报告。

  1. build.gradle 中添加自定义任务

    groovy 复制代码
    // 定义一个生成 dependencies.xml 的任务 tasks.register('generateDependenciesXml') {
        group = 'reporting' // 将任务分组到 'reporting' 下,便于管理 description = 'Generates an XML file containing project dependencies.'
    
        // 指定任务在项目评估完成后执行,以确保依赖图已解析 doLast {
            // 获取项目的所有配置(如 implementation, testImplementation 等)
            def configurations = project.configurations
            // 创建一个 XML 文档结构 def xmlOutput = new groovy.xml.MarkupBuilder(new FileWriter("${buildDir}/dependencies.xml"))
    
            xmlOutput.dependencies {
                configurations.each { config ->
                    // 过滤掉非可解析的配置,避免错误 if (config.canBeResolved) {
                        try {
                            config.resolvedConfiguration.resolvedArtifacts.each { artifact ->
                                dependency {
                                    groupId(artifact.moduleVersion.id.group)
                                    artifactId(artifact.name)
                                    version(artifact.moduleVersion.id.version)
                                    configuration(config.name)
                                    classifier(artifact.classifier ?: '')
                                    type(artifact.extension)
                                }
                            }
                        } catch (Exception e) {
                            // 某些配置可能无法解析,例如 'detachedConfiguration',这里忽略错误 project.logger.info("无法解析配置 ${config.name} 的依赖: ${e.message}")
                        }
                    }
                }
            }
            println "依赖文件已生成: ${buildDir}/dependencies.xml"
        }
    }
    
    // 将生成依赖文件的任务关联到 assemble 任务,使得每次打包时自动执行
    tasks.named('assemble') {
        dependsOn tasks.named('generateDependenciesXml')
    }
  2. 执行任务

    • 单独生成依赖文件:./gradlew generateDependenciesXml
    • 执行打包(如 jar)时,由于 assemble 依赖了该任务,dependencies.xml 会自动生成在 build/ 目录下。

方案二:集成 Maven 的 dependency:tree 目标(适用于混合项目)

如果你的项目同时支持 Maven,或者你需要与 Maven 格式完全兼容的 dependencies.xml,可以使用 maven 插件。

  1. 应用 Maven 插件并添加自定义任务

    groovy 复制代码
    // 应用 Maven 插件    apply plugin: 'maven'
    
    // 自定义任务,调用 Maven 的 dependency:tree 并输出为 XML
    tasks.register('generateMavenDependencyTreeXml') {
        group = 'reporting'
        description = 'Generates Maven-style dependency tree in XML format using maven-dependency-plugin.'
    
        doLast {
            // 执行 Maven 目标。这需要本地已安装 Maven 且项目根目录有可用的 pom.xml。
            // 注意:这是一种变通方法,并非纯 Gradle 方式。
            exec {
                workingDir project.rootDir
                commandLine 'mvn', 'dependency:tree', '-DoutputFile=dependencies.xml', '-DoutputType=xml'
            }
            // 将生成的文件移动到 build 目录 ant.move(file: "${project.rootDir}/dependencies.xml",
                     tofile: "${buildDir}/dependencies.xml")
            println "Maven 格式依赖文件已生成: ${buildDir}/dependencies.xml"
        }
    }

    注意 :此方案依赖于外部 Maven 命令和 pom.xml 文件,通常仅在需要与现有 Maven 工具链兼容时使用。

方案对比

特性 方案一(纯 Gradle) 方案二(Maven 集成)
原理 利用 Gradle 的配置 API 直接解析依赖图并生成 XML 。 调用外部 Maven 命令 dependency:tree 生成报告。
兼容性 纯 Gradle 项目,无需其他工具。 需要本地安装 Maven 并存在 pom.xml
输出格式 自定义 XML 结构,可灵活定义节点。 标准的 Maven dependency:tree XML 格式。
集成度 高,与 Gradle 构建生命周期无缝集成。 低,依赖于外部进程。
推荐场景 绝大多数 Gradle 项目,希望自动化生成依赖清单。 需要与下游 Maven 工具链保持格式严格一致的项目。

关键配置解析

  • configurations :代表项目的依赖配置集合(如 implementation, compileOnly, runtimeOnly 等)。
  • canBeResolved :用于过滤掉那些仅用于声明依赖而不用于解析的配置(如 compileClasspath 是可解析的,而 compileOnly 在旧版本中可能不可解析)。
  • resolvedConfiguration.resolvedArtifacts:获取已解析的依赖构件列表,包含组、名称、版本等详细信息 。
  • 任务依赖 (dependsOn) :通过 assemble.dependsOn generateDependenciesXml确保打包前生成依赖文件,实现自动化 。

参考来源

相关推荐
Flynt5 小时前
把公司项目迁到 Spring Boot 4.0:编译通过只是开始
java·spring boot·后端
Tangyuewei5 小时前
给老 Spring 项目装个 AI Agent
java·人工智能·spring
她的男孩6 小时前
多租户和数据权限怎么共存?扒完拦截器注册链路,我找到 4 个隐蔽的坑
java·后端·架构
小溪学编程6 小时前
Java BufferedReader 详解:从基础用法到性能优化
java·python·性能优化
HZero.chen6 小时前
Java 匿名类简介
java·匿名类
用户3126874877206 小时前
Java 泛型擦除到底擦掉了什么?类型安全与桥接方法深度拆解
java
暖焰核心6 小时前
继承全解——继承、默认成员函数、切片、隐藏与虚继承
java·前端·javascript
君顾17 小时前
外卖CPS系统开发实战指南:从架构设计到部署全流程解析
java·开发语言·外卖
奇牙coding1237 小时前
GPT-5.5 升级 GPT-5.6 接入指南:流式调用配置与常见问题
java·网络·gpt·ai
老刘的望远镜7 小时前
AgentScope Java 从零(03):Agent 的记性默认全开,我在第 50 轮翻了车
java·开发语言·javascript