Gradle多模块项目:构建与消费内部插件的实战指南

Gradle多模块项目:构建与消费内部插件的实战指南

本文旨在解决gradle多模块项目中,内部开发的插件无法被同项目其他模块识别和使用的问题。通过引入gradle的复合构建(composite builds)机制,特别是利用`includebuild()`在根`settings.gradle.kts`中声明插件模块,并为插件模块配置独立的`settings.gradle.kts`文件,确保gradle能够正确地构建并解析内部插件,从而实现插件的顺畅消费。

问题概述:多模块项目中的插件未找到

在复杂的Gradle多模块项目中,开发者常会创建自定义插件来封装通用配置或业务逻辑。然而,当尝试在同一个多模块项目中的其他模块(例如my-implementation)中应用这些内部插件(例如my-gradle-plugin)时,Gradle可能会报告“Plugin was not found”的错误。

典型的错误信息如下:

* What went wrong:Plugin [id: 'org.my.gradle.plugin', version: '0.0.3-SNAPSHOT'] was not found in any of the following sources:- Gradle Core Plugins (plugin is not in 'org.gradle' namespace)- Plugin Repositories (could not resolve plugin artifact 'org.my.gradle.plugin:org.my.gradle.plugin.gradle.plugin:0.0.3-SNAPSHOT')  Searched in the following repositories:    MavenLocal(file:/home/jenkins/.m2/repository/)    maven(https://xyz)    Gradle Central Plugin Repository    MavenRepo

这个错误表明Gradle在配置的插件仓库中(包括本地Maven仓库、远程Maven仓库和Gradle插件门户)未能找到对应的插件构件。尽管在根settings.gradle.kts的pluginManagement中已经配置了mavenLocal()和其他仓库,并且通过resolutionStrategy指定了版本,但Gradle似乎并未意识到需要先构建项目内部的my-gradle-plugin模块,然后才能使用它。

解决方案核心:利用复合构建(Composite Builds)

解决此问题的关键在于明确告诉Gradle,my-gradle-plugin模块是一个独立的构建,其产物(即插件)需要在主构建的早期阶段被解析和使用。这可以通过Gradle的复合构建(Composite Builds)功能实现,具体步骤如下:

为插件模块创建独立的settings.gradle.kts

首先,在你的插件模块(例如my-gradle-plugin)的根目录下,创建一个空的settings.gradle.kts文件。这个文件虽然可以为空,但它的存在至关重要,它标志着my-gradle-plugin目录本身是一个独立的Gradle构建,而不是主构建的一个简单子项目。

+ root  + my-gradle-plugin/    + build.gradle.kts    + settings.gradle.kts // <-- 新增此文件

在根settings.gradle.kts中使用includeBuild()

在项目的根settings.gradle.kts文件中,通过pluginManagement块内的includeBuild()方法来引入插件模块。这会将插件模块作为一个复合构建的一部分,指示Gradle在解析插件时,首先考虑这个内部构建提供的插件。

Word-As-Image for Semantic Typography Word-As-Image for Semantic Typography

文字变形艺术字、文字变形象形字

Word-As-Image for Semantic Typography 62 查看详情 Word-As-Image for Semantic Typography

修改后的根settings.gradle.kts示例如下:

// ./root/settings.gradle.ktsrootProject.name = "root-project"// 包含其他子项目include("my-api", "my-implementation")pluginManagement {    // 使用 includeBuild() 声明插件模块为一个独立的构建    // Gradle 会在解析插件时,优先从这个构建中查找    includeBuild("my-gradle-plugin")    repositories {        mavenLocal()        maven { url = uri("https://xyz") }        gradlePluginPortal()        mavenCentral()    }    resolutionStrategy {        val version: String by settings        eachPlugin {            // 如果请求的插件ID与内部插件匹配,则使用当前项目版本            if (requested.id.id == "org.my.gradle.plugin") {                useVersion(version)            }        }    }}

解释:

includeBuild(“my-gradle-plugin”):告诉Gradle将my-gradle-plugin目录视为一个独立的构建,并且其提供的插件应该在主构建的插件解析阶段可用。resolutionStrategy:此部分确保了当其他模块请求org.my.gradle.plugin时,会使用在根gradle.properties中定义的项目版本(例如0.0.3-SNAPSHOT)。

插件的消费方式

完成上述配置后,其他模块就可以像使用任何外部插件一样,在它们的build.gradle.kts文件中应用内部插件了。

// ./my-implementation/build.gradle.ktsplugins {   // 当使用 includeBuild() 引入内部插件时,   // 推荐使用 "internal" 作为版本,这是一种约定,表示插件来自当前构建环境   id("org.my.gradle.plugin") version "internal"}

注意事项:

版本号 internal: 在复合构建中,为通过includeBuild()引入的插件指定版本时,通常使用一个特殊的值,例如”internal”。这并非实际的版本号,而是一种约定,表明该插件是从当前构建的“内部”来源获取的,而不是从外部仓库下载。Gradle在解析时,会根据includeBuild的声明找到正确的插件。Gradle版本兼容性: 这种复合构建的插件解析机制在Gradle 7.5+版本中经过验证可行。对于更早的Gradle版本,行为可能有所不同,建议查阅对应版本的官方文档。

工作原理与总结

通过在插件模块中添加一个空的settings.gradle.kts文件,并修改根settings.gradle.kts以includeBuild(“my-gradle-plugin”),我们有效地将插件模块提升为一个独立的“复合构建”。Gradle在执行主构建时,会首先处理这个复合构建,确保插件能够被编译和打包。随后,当主构建中的其他模块尝试解析org.my.gradle.plugin时,Gradle会知道去这个内部复合构建中查找,而不是仅仅依赖外部插件仓库。

这种方法使得在大型多模块项目中管理和消费内部开发的Gradle插件变得更加无缝,极大地简化了开发和测试流程。它避免了将内部插件发布到本地Maven仓库的繁琐步骤,直接在项目内部实现了插件的构建和消费闭环。

以上就是Gradle多模块项目:构建与消费内部插件的实战指南的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1051408.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年12月2日 04:33:05
下一篇 2025年12月2日 04:33:27

相关推荐

  • WordPress:批量更新文章元数据的高效策略

    本文详细介绍了在wordpress中为单个或批量文章更新自定义元数据(meta value)的两种主要方法。首先,通过定义文章id数组并使用`foreach`循环实现精确指定文章的元数据更新。其次,演示了如何利用`wp_query`根据特定条件(如文章类型、分类)筛选文章,并对其元数据进行批量操作。…

    2025年12月12日
    000
  • 动态化WordPress查询:使用ACF字段设置category_name参数

    本文旨在解决在WordPress `WP_Query` 中使用高级自定义字段(ACF)值动态设置 `category_name` 参数时常见的语法错误。我们将深入探讨为何不能在PHP代码块内部嵌套 `php echo … ?>` 标签,并提供正确的解决方案,即直接引用PHP变量。通…

    2025年12月12日
    000
  • MySQL中如何正确更新现有记录:告别INSERT WHERE的误区

    本文旨在解决mysql数据库操作中一个常见的误区:尝试使用`insert`语句结合`where`子句来更新现有数据。我们将明确指出`insert`与`update`语句的核心区别,并通过具体示例,详细演示如何使用正确的`update`语句及其`set`和`where`子句来精确地修改数据库中的现有记…

    2025年12月12日
    000
  • WordPress教程:如何在其他页面动态获取并显示首页特色图片

    本教程详细介绍了如何在wordpress自定义模板中,动态获取并显示网站首页的特色图片url。通过利用wordpress内置函数,您可以轻松实现跨页面图片资源的引用,无需硬编码,从而提升网站内容的灵活性和可维护性,特别适用于需要在一个页面展示另一个页面(如首页)特定内容的场景。 在WordPress…

    2025年12月12日
    000
  • 高效从非规范化MySQL表提取与排序PHP用户数据

    本教程旨在解决从非规范化mysql表(如wordpress插件生成的数据表)中高效提取并重构用户数据的挑战。面对包含`app_id`、`field_id`和`value`列的大型数据集,文章将展示如何通过优化sql查询和php数据处理,避免多次数据库查询导致的性能瓶颈,将分散的用户信息整合为结构清晰…

    2025年12月12日
    000
  • API 调用返回 HTML 而非 JSON:解决自动重定向问题

    本文旨在解决在与外部api交互时,尤其是在支付网关集成中,api返回html而非预期json的问题。核心原因在于http 302重定向被curl自动跟踪。教程将详细解释如何通过禁用curl的自动重定向功能 (`curlopt_followlocation => false`) 来获取原始响应,…

    2025年12月12日
    000
  • 如何在 WP_Query 中使用 ACF 动态设置分类名称

    本教程将指导您如何在 wordpress 的 `wp_query` 循环中,利用高级自定义字段 (acf) 动态地设置文章分类名称,取代硬编码的静态值。我们将重点讲解如何正确引用 acf 变量,避免常见的 php 语法错误,从而实现更灵活、可配置的内容展示。 在 WordPress 开发中,WP_Q…

    2025年12月12日
    000
  • php数据如何制作在线投票系统_php数据投票功能逻辑与实现

    在线投票系统通过PHP与MySQL实现,核心包括展示选项、接收投票、记录数据、防重及显示结果。首先设计options表存储候选信息,votes_log表记录IP与投票关联以防止重复提交。前端用PHP读取选项并生成投票表单;用户提交后,后端验证是否已投票(基于IP),确保唯一性,并通过事务机制同步更新…

    2025年12月12日
    000
  • 在WordPress作者页面添加自定义文本字段及富文本编辑器教程

    本教程旨在指导WordPress用户如何在作者(用户)资料页面添加自定义文本字段,特别是富文本编辑器(WYSIWYG),并将其内容展示在作者页面。文章将介绍两种主要方法:通过代码使用`user_contactmethods`钩子,以及利用Advanced Custom Fields (ACF) 插件…

    2025年12月12日 好文分享
    000
  • 正确使用SQL进行条件性数据更新:UPDATE语句详解

    本文旨在解决在sql数据库中,尤其是在mysql环境下,如何根据特定条件更新现有记录的常见困惑。许多开发者误将`insert`语句与`where`子句结合使用,期望实现条件更新,但这是错误的语法。本教程将详细解释`insert`和`update`语句的根本区别,并提供使用`update`语句进行精确…

    2025年12月12日
    000
  • PHP数组操作:高效为数组内每个子数组添加公共键值对

    本教程详细阐述了在php中如何高效地向一个包含多个子数组的集合中,为每个子数组动态添加一个或多个新的公共键值对。通过遍历数组并结合`array_merge()`函数,我们可以轻松实现数据结构的批量更新,确保每个子项都拥有所需的新属性,适用于处理类似商品列表或用户信息等场景。 在PHP开发中,我们经常…

    2025年12月12日
    000
  • 如何在PHP中将MySQL查询结果中的逗号分隔值独立显示为多条记录

    本教程旨在解决从mysql数据库中获取逗号分隔值(如姓名列表)后,如何在php中将其独立显示为多条记录的常见问题。我们将详细介绍如何利用php的`explode()`函数处理这类数据,并提供示例代码。同时,文章将强调这种数据库设计模式的潜在风险,并建议更优的数据库规范化实践。 理解问题背景 在实际开…

    2025年12月12日
    000
  • WordPress跨页面获取首页特色图片教程

    本教程详细介绍了如何在wordpress中动态获取并显示静态首页的特色图片。通过利用wordpress内置函数,您可以轻松地在网站的任何其他页面或模板中,获取到首页设置的特色图片id,并将其以完整的图片标签或纯图片url的形式展示出来,实现内容的灵活调用和展示。 在WordPress网站开发中,有时…

    2025年12月12日
    000
  • 在WordPress作者页面添加自定义文本字段及WYSIWYG编辑器的方法

    本教程详细介绍了如何在WordPress作者页面和用户资料中添加自定义文本字段,并支持WYSIWYG编辑器。文章提供了两种实现方案:通过`user_contactmethods`钩子进行代码定制,以及利用Advanced Custom Fields (ACF)插件实现无代码配置,帮助用户灵活扩展Wo…

    2025年12月12日
    000
  • PHP代码怎么实现分页显示功能_PHP分页算法与LIMIT子句应用

    分页功能通过LIMIT子句控制查询条数,结合URL传参计算偏移量实现。1. 使用LIMIT offset,per_page限制结果集;2. PHP获取页码并验证,计算偏移量;3. 查询总记录数并分页显示数据;4. 输出页码导航链接;5. 注意参数过滤与性能优化。 实现分页显示功能在PHP开发中非常常…

    2025年12月12日
    000
  • WordPress循环中动态生成JSON并避免末尾逗号的技巧

    本文探讨在WordPress循环中动态生成JSON结构时,如何避免因手动拼接字符串而产生的末尾逗号问题。文章将介绍两种解决方案:一种是利用`WP_Query`的内部属性进行条件判断来控制逗号输出,另一种是推荐使用PHP内置的`json_encode`函数,通过构建完整的PHP数组结构再统一编码,以确…

    2025年12月12日
    000
  • PHP数组操作:为嵌套数组元素统一添加新属性

    本教程详细阐述了在php中如何高效地向一个包含多个关联数组的数组中的每个子元素统一添加新的键值对。通过遍历原数组并结合`array_merge`函数,我们可以轻松地扩展数据结构,为每个现有记录注入新的公共属性,从而生成满足特定需求的新数组。 在PHP开发中,我们经常需要处理包含多条记录的数据集,这些…

    2025年12月12日
    000
  • PHP与XPath:高效合并XML日历中的同日事件

    本教程详细介绍了如何使用php的simplexml和xpath功能,处理结构化xml日历数据。面对多个事件在同一日期分散显示的问题,我们将学习如何通过xpath查询提取唯一日期,并在此基础上将同一日期的所有事件描述进行分组展示,从而实现清晰、聚合的日历视图,避免重复日期标题,提升数据可读性。 引言 …

    2025年12月12日
    000
  • php数据如何安全地连接MySQL数据库_php数据操作中防止SQL注入的技巧

    使用PDO或MySQLi预处理语句可有效防止SQL注入,避免拼接SQL字符串,结合输入验证与最小权限原则,确保数据库操作安全。 在PHP开发中,安全地连接MySQL数据库并防止SQL注入是保障应用数据安全的关键环节。很多开发者因使用过时的方法或忽略输入验证,导致系统面临严重风险。以下是一些实用且有效…

    2025年12月12日
    000
  • php怎么跳转网页_php实现页面跳转的几种方法与适用场景

    首选header()函数跳转,需在无输出前调用并加exit;2. 已有输出时用JavaScript跳转;3. 需延迟跳转可用meta标签;4. SEO优化选择301重定向。 在PHP开发中,页面跳转是常见的需求,比如用户登录后跳转到首页、表单提交后跳转到结果页等。实现跳转的方法有多种,不同场景下应选…

    2025年12月12日
    000

发表回复

登录后才能评论
关注微信