基于Kotlin DSL的多模块Gradle项目:如何生成含所有子模块的Jar包?
合并Gradle子模块代码到父模块Jar(Kotlin DSL实现)
核心思路
在父模块中创建自定义Jar任务,依赖所有子模块的编译任务,收集子模块的编译产物(class文件)打包成一个Jar,同时将这个自定义Jar配置为Maven发布的主制品。
父模块build.gradle.kts配置代码
plugins { `java-library` `maven-publish` kotlin("jvm") version "1.9.20" // 替换为你的项目Kotlin版本 } // 可选:禁用父模块默认的空Jar任务 tasks.jar { enabled = false } // 注册合并子模块代码的自定义Jar任务 val combinedJar by tasks.registering(Jar::class) { archiveBaseName.set(project.name) archiveClassifier.set("") // 保持Jar名称与父模块一致,无额外分类器 // 确保所有子模块先完成编译 dependsOn(subprojects.map { it.tasks.named("classes") }) // 收集所有子模块的编译输出(Kotlin/Java class文件) subprojects.forEach { subproject -> from(subproject.sourceSets.main.get().output) } } // 配置Maven发布,使用自定义合并Jar作为主制品 publishing { publications { create<MavenPublication>("maven") { // 关联合并后的主Jar artifact(combinedJar) // 可选:合并源码Jar(按需启用) val combinedSourcesJar by tasks.registering(Jar::class) { archiveClassifier.set("sources") subprojects.forEach { subproject -> from(subproject.sourceSets.main.get().allSource) } } artifact(combinedSourcesJar) // 可选:合并JavaDoc Jar(需子模块配置javadoc任务) val combinedJavadocJar by tasks.registering(Jar::class) { archiveClassifier.set("javadoc") dependsOn(subprojects.map { it.tasks.named("javadoc") }) subprojects.forEach { subproject -> from(subproject.tasks.named("javadoc")) } } artifact(combinedJavadocJar) } } // 配置Maven仓库地址(替换为你的目标仓库) repositories { maven { url = uri("https://your-maven-repo-url") // 仓库认证(按需添加) credentials { username = System.getenv("MAVEN_USER") password = System.getenv("MAVEN_PWD") } } } }
关键说明
- 子模块需确保应用
kotlin-jvm或java-library插件,这样才能提供sourceSets.main.output和classes编译任务。 - 该方案仅打包项目自身的class文件,不包含任何依赖库或Kotlin标准库,完全符合非胖Jar的需求。
- 子模块的默认Jar仍会正常生成(若需禁用,可在子模块的
build.gradle.kts中添加tasks.jar { enabled = false })。 - 执行
./gradlew combinedJar可直接生成合并后的Jar,路径为父模块的build/libs/目录下。 - 执行
./gradlew publish可将合并后的Jar(及可选的源码、JavaDoc Jar)发布到配置的Maven仓库。
内容的提问来源于stack exchange,提问作者Madoc
相关产品推荐
相关产品推荐

