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 都是一个值得考虑的工具。更多用例和说明,请参照:

相关推荐
☆致夏☆3 分钟前
Maven入门到精通
java·maven
小杨同学yx9 分钟前
tomcat知识点讲解
java·tomcat·firefox
小杨同学yx11 分钟前
tomcat手写流程思路
java·tomcat·firefox
呼啦啦圈1 小时前
get请求中文字符参数乱码问题
java·javascript
_码农121381 小时前
简单spring boot项目,之前练习的,现在好像没有达到效果
java·spring boot·后端
期待のcode1 小时前
配置Mybatis环境
java·tomcat·mybatis
Fly-ping2 小时前
【后端】java 抽象类和接口的介绍和区别
java·开发语言
平生不喜凡桃李2 小时前
Linux 线程同步与互斥
java·jvm·redis
Dnui_King2 小时前
Oracle 在线重定义
java·服务器·前端
回家路上绕了弯2 小时前
Java 并发编程常见问题及解决方案
java·后端