人间工作P 人间工作P
主站 (opens new window)
首页
  • Bukkit开发教程
投喂
关于
  • 分类
  • 标签
  • 时间线
  • 友情链接

人间工作P

我每天都好困… 最近在学习和进行 VOCALOID 创作
主站 (opens new window)
首页
  • Bukkit开发教程
投喂
关于
  • 分类
  • 标签
  • 时间线
  • 友情链接
  • Gradle 的一些小技巧

    • Maven 仓库添加
      • 忽略 Java 版本需求
        • 依赖添加
          • 从其它子模块合并源码Jar
          MrXiaoM
          2025-08-28
          Gradle
          目录

          Gradle 的一些小技巧

          讲一点自己的心得

          整理一些小技巧,不定期更新。以 kotlin dsl (build.gradle.kts) 为主。

          # Maven 仓库添加

          一般来说,我们通常直接在 repositories 里添加仓库,越在前面的优先级越高。

          repositories {
              maven("https://mirrors.huaweicloud.com/repository/maven/")
              mavenCentral()
          }
          
          1
          2
          3
          4

          但是,一些仓库在不同地区的速度不同,例如上述的华为云镜像在 Github Actions 上的效果就不一定有 Maven Central 官方仓库好。当我们需要这个项目仅在中国地区的机器上运行时使用该仓库,可以使用 java.util.Locale 实现这个功能。

          import java.util.Locale
          
          repositories {
              if (Locale.getDefault().country == "CN") {
                  maven("https://mirrors.huaweicloud.com/repository/maven/")
              }
              mavenCentral()
          }
          
          
          1
          2
          3
          4
          5
          6
          7
          8
          9

          # 忽略 Java 版本需求

          java {
              disableAutoTargetJvm()
          }
          
          1
          2
          3

          假设你在使用 Java 17 开发项目作为过渡,引用 Java 21 的依赖 purpur-api:1.21.11,不忽略依赖的 Java 版本需求就会出问题。

          如果不忽略,依赖 paper-api、velocity 之类使用 Gradle 构建的包的时候,会因为 Gradle 的检查太过严格,出现以下报错

          报错内容
          项目名:main: No matching variant of org.purpurmc.purpur:purpur-api:1.21.11-R0.1-SNAPSHOT was found. The consumer was configured to find a library for use during compile-time, compatible with Java 17, preferably in the form of class files, preferably optimized for standard JVMs, and its dependencies declared externally but:
            - Variant 'apiElements' capabilities com.destroystokyo.paper:paper-api:1.21.11-R0.1-SNAPSHOT and com.destroystokyo.paper:paper-mojangapi:1.21.11-R0.1-SNAPSHOT and io.papermc.paper:paper-mojangapi:1.21.11-R0.1-SNAPSHOT and org.bukkit:bukkit:1.21.11-R0.1-SNAPSHOT and org.purpurmc.purpur:purpur-api:1.21.11-R0.1-SNAPSHOT and org.spigotmc:spigot-api:1.21.11-R0.1-SNAPSHOT declares a library for use during compile-time, packaged as a jar, and its dependencies declared externally:
                - Incompatible because this component declares a component, compatible with Java 21 and the consumer needed a component, compatible with Java 17
            - Variant 'javadocElements' capabilities com.destroystokyo.paper:paper-api:1.21.11-R0.1-SNAPSHOT and com.destroystokyo.paper:paper-mojangapi:1.21.11-R0.1-SNAPSHOT and io.papermc.paper:paper-mojangapi:1.21.11-R0.1-SNAPSHOT and org.bukkit:bukkit:1.21.11-R0.1-SNAPSHOT and org.purpurmc.purpur:purpur-api:1.21.11-R0.1-SNAPSHOT and org.spigotmc:spigot-api:1.21.11-R0.1-SNAPSHOT declares a component for use during runtime, and its dependencies declared externally:
                - Incompatible because this component declares documentation and the consumer needed a library
            - Variant 'runtimeElements' capabilities com.destroystokyo.paper:paper-api:1.21.11-R0.1-SNAPSHOT and com.destroystokyo.paper:paper-mojangapi:1.21.11-R0.1-SNAPSHOT and io.papermc.paper:paper-mojangapi:1.21.11-R0.1-SNAPSHOT and org.bukkit:bukkit:1.21.11-R0.1-SNAPSHOT and org.purpurmc.purpur:purpur-api:1.21.11-R0.1-SNAPSHOT and org.spigotmc:spigot-api:1.21.11-R0.1-SNAPSHOT declares a library for use during runtime, packaged as a jar, and its dependencies declared externally:
                - Incompatible because this component declares a component, compatible with Java 21 and the consumer needed a component, compatible with Java 17
            - Variant 'sourcesElements' capabilities com.destroystokyo.paper:paper-api:1.21.11-R0.1-SNAPSHOT and com.destroystokyo.paper:paper-mojangapi:1.21.11-R0.1-SNAPSHOT and io.papermc.paper:paper-mojangapi:1.21.11-R0.1-SNAPSHOT and org.bukkit:bukkit:1.21.11-R0.1-SNAPSHOT and org.purpurmc.purpur:purpur-api:1.21.11-R0.1-SNAPSHOT and org.spigotmc:spigot-api:1.21.11-R0.1-SNAPSHOT declares a component for use during runtime, and its dependencies declared externally:
                - Incompatible because this component declares documentation and the consumer needed a library
          
          1
          2
          3
          4
          5
          6
          7
          8
          9

          # 依赖添加

          实际上,依赖可以使用以下三种格式

          dependencies {
              // 这两种适用于一般情况
              配置名(group="分组", name="构件名", version="版本", classifier="分类", ext="扩展名")
              配置名("分组:构件名:版本:分类@扩展名")
              // 这种适用于在 subprojects 块中,也就是项目还在早期加载阶段,出不来配置名补全的时候使用
              add("配置名", "分组:构件名:版本:分类@扩展名")
          }
          
          1
          2
          3
          4
          5
          6
          7

          我们最常用的是以下格式

          配置名("分组:构件名:版本:分类@扩展名")
          // 例如
          compileOnly("com.google.code:gson:2.8.0")
          
          1
          2
          3

          其中,分类默认为"",扩展名默认为"jar",这俩可以不输入。

          最终会将组名的.替换为/,下载 组名/构件名/版本/构件名-版本(-分类).扩展名 这个文件,例如上述的 gson 为 com/google/code/gson/2.8.0/gson-2.8.0.jar。

          分类通常用于 shadowJar (opens new window),例如通过 shadow 打包的文件名都会有个 -all 结尾,这个 all 就是分类。

          为什么我要研究这个呢?因为我在 lumine 的仓库遇到了这玩意 (opens new window)。

          org/spigotmc/spigot-1.7.10/dev/spigot-1.7.10-dev.8.jar

          别看了,Nexus Repository 给的 Usage 是错的,在这种情况下,特别还是不知道上面这些知识的时候,你要怎么引用这个依赖?

          了解以上的知识后,就可以反向猜出

          • 分组为 org.spigotmc
          • 构件名为 spigot-1.7.10
          • 版本为 dev
          • 扩展名为 8.jar

          是的,扩展名为 8.jar,这是哪个神人想出来这样发版的,给我气笑了。最终可以这样在 Gradle 添加依赖。

          compileOnly(group="org.spigotmc", name="spigot-1.7.10", version="dev", ext="8.jar")
          compileOnly("org.spigotmc:spigot-1.7.10:dev@8.jar")
          add("compileOnly", "org.spigotmc:spigot-1.7.10:dev@8.jar")
          
          1
          2
          3

          # 从其它子模块合并源码Jar

          我们可以简单地添加以下配置,以便在构建的时候生成 -sources.jar 和 -javadoc.jar,这也会自动添加到 publishing 配置。

          java {
              withSourcesJar()
              withJavadocJar()
          }
          
          1
          2
          3
          4

          但是有时会出现一种情况,就是一个模块只是为了分享共同接口,没有必要单开一个模块,但是又必须开一个模块,否则会出现循环引用依赖问题。

          在发布到 maven 仓库的时候,我想让 shared 模块的源代码和 javadoc 都打包到主要模块里面,可以这样做:

          tasks {
              // 获取当前模块的 sourcesJar 任务
              getByName<Jar>(project.sourceSets.main.get().sourcesJarTaskName) {
                  // 将 shared 模块的源码全部加进来
                  from(project(":shared").sourceSets.main.get().allSource)
              }
              // 获取当前模块的 javadoc 任务
              // 之所以不获取 javadocJar,是因为 javadocJar 是没法合并的,只能从生成这块下手    
              getByName<Javadoc>(sourceSets.main.get().javadocTaskName) {
                  // 获取 shared 模块的 javadoc 任务
                  val task = project(":shared").run {
                      val taskName = this@run.sourceSets.main.get().javadocTaskName
                      this@run.tasks.named<Javadoc>(taskName).get()
                  }
                  // 将 javadoc 任务的源码全部加到当前任务
                  source += task.source
              }
          }
          
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          编辑 (opens new window)
          #Gradle#Java#编程
          上次更新: 2026/03/03, 13:48:40
          最近更新
          01
          制作可爱的 Q版 VRoid Studio 模型
          04-12
          02
          使用 HAProxy 转发来自不同域名的地址到不同的 Minecraft 服务器
          04-03
          03
          在构建/运行 Flutter 应用时添加环境变量,作出差异化调整
          03-30
          更多文章>
          Theme fork from Vdoing | Copyright © 2018-2026 人间工作P | 友情链接
          • 跟随系统
          • 浅色模式
          • 深色模式
          • 阅读模式