Shadow Gradle Plugin 9 发布了

Shadow 9 迎来了重要更新,它使用了 Kotlin 进行完全重写,解决了之前版本遗留的一系列问题,并带来了性能和可维护性的显著提升。 Shadow Gradle Plugin 本身是一个用于 Gradle 平台的插件,主要功能是创建包含所有依赖的 "fat JAR" (或称 uber-jar),是 Maven Shade Plugin 的一个强大替代品。

Shadow 的核心优势

Shadow 插件主要解决两大核心问题:

  1. 创建可执行的 JAR 包 :这是部署应用程序时的主要场景。Shadow 可以将你的应用代码以及所有依赖的库文件打包成一个单一的、可执行的 JAR 文件。这个 JAR 文件不包含 JRE,因此目标系统上需要有 Java 运行环境。你可以通过简单的命令 java -jar your-app-all.jar 来运行你的应用。
  2. 为库打包和重定位依赖:这是库作者面临的典型场景。当你的库依赖了某个第三方库(例如 Guava 或 ASM),而使用你的库的应用又依赖了同一个库的不同版本时,就可能产生类路径冲突 (classpath conflicts)。Shadow 能够重命名(重定位)你的库所依赖的包名,从而避免这种冲突。

Shadow 9 的主要变化

  • Kotlin 重写:整个插件使用 Kotlin 进行了重写,带来了更好的性能和可维护性。
  • 最低要求:需要 Gradle 8.11+ 和 Java 11+。
  • 插件 ID 变更 :插件 ID 从 com.github.johnrengelman.shadow 变更为 com.gradleup.shadow
  • 默认 duplicatesStrategy 变更 :默认的重复文件处理策略从 EXCLUDE 变为了 INCLUDE。这意味着默认情况下,最后遇到的同名文件会覆盖之前的文件。

快速上手

你可以通过 plugins 代码块来应用 Shadow 插件。

kotlin 复制代码
plugins {
  java
  id("com.gradleup.shadow") version "<最新版本>"
}

注意 : 请将 <最新版本> 替换为当前最新的 Shadow 插件版本。你可以在 Gradle Plugin Portal 上找到最新版本。

应用插件后,Shadow 会自动配置以下内容:

  • 添加一个名为 shadowJarShadowJar 类型的 Task。
  • 配置 shadowJar 任务以包含 main sourceSet 的所有源码和 runtimeClasspath configuration 的所有依赖。
  • shadowJar 生成的 JAR 文件添加 all 作为 classifier,例如 my-app-1.0-all.jar
  • 自动从标准的 jar 任务中继承 Manifest 配置。
  • 自动排除 JAR 索引和签名文件。

简单使用示例

示例 1: 创建一个可执行的 Fat JAR

假设你有一个使用了 application 插件的 Java 或 Kotlin 项目。

kotlin 复制代码
plugins {
    application
    id("com.gradleup.shadow")
}

application {
    mainClass = "com.example.Main"
}

// shadowJar 任务会自动从 application 插件中获取 mainClass 配置
// 并将其设置到 MANIFEST.MF 文件中

配置完成后,运行 ./gradlew shadowJar 即可在 build/libs 目录下生成一个名为 <项目名>-<版本号>-all.jar 的 fat JAR 文件。

你可以通过 java -jar build/libs/your-app-1.0-all.jar 来直接运行它。

或者,你也可以执行 ./gradlew installShadowDist 或者 ./gradlew shadowDistZip 用来生成包含 wrapper 和 JAR 的可执行文件。

示例 2: 在库中重定位包名以避免冲突

这是一个非常实用的功能,特别是对于库的开发者。

kotlin 复制代码
plugins {
    java
    id("com.gradleup.shadow")
}

dependencies {
    implementation("com.google.guava:guava:31.1-jre")
}

tasks.shadowJar {
    // 重定位 Guava 的包名
    relocate("com.google.common", "shadow.com.google.common")
}

在上面的例子中,所有 com.google.common 包下的类,在打包后的 JAR 文件中都会被移动到 shadow.com.google.common 包下,并且所有对这些类的引用也会被自动修改。

示例 3: 合并 Service Descriptor 文件

Java 的 ServiceLoader 机制依赖于 META-INF/services/ 目录下的服务定义文件。当多个依赖包含同名的服务文件时,你需要将它们合并。

kotlin 复制代码
tasks.shadowJar {
    mergeServiceFiles()
}

这会自动合并所有在 META-INF/services 目录下的同名文件。

总结

Shadow Gradle Plugin 9 通过其强大的功能和现在更为现代化的代码基础,为 Gradle 用户提供了一个创建 fat JAR 和管理复杂依赖场景的优秀解决方案。无论你是需要部署一个独立的应用,还是希望创建一个健壮、无依赖冲突的库,Shadow 都是一个值得考虑的工具。更多用例和说明,请参照:

相关推荐
带刺的坐椅6 分钟前
Solon 权限认证之 Sa-Token 的使用与详解
java·sa-token·web·solon
麦兜*30 分钟前
MongoDB 源码编译与调试:深入理解存储引擎设计 内容详细
java·数据库·spring boot·mongodb·spring
编啊编程啊程1 小时前
响应式编程框架Reactor【9】
java·网络·python·spring·tomcat·maven·hibernate
evolution_language1 小时前
LintCode第401题-排序矩阵中的从小到大第k个数
java·算法·矩阵·排序算法·堆排序·练码精选100题
_Jimmy_1 小时前
java讲解自己对业务架构、数据架构、应用架构的理解
java
资源开发与学习1 小时前
Java大模型工程能力必修课,LangChain4j 入门到实践
java
AAA修煤气灶刘哥2 小时前
从全表扫描到 0.1 秒查询:数据库索引吃透这篇,面试不慌
java·数据库·后端
柯南二号2 小时前
【Java后端】Spring Boot 全局域名替换
java·开发语言·spring boot
Swift社区3 小时前
Java 常见异常系列:NumberFormatException 数字格式异常
java·开发语言
刘火锅3 小时前
设计模式-状态模式 Java
java·设计模式·状态模式