Skip to content

打包 JAR

普通 JAR

kotlin
tasks.named<Jar>("jar") {
    // Manifest 配置
    manifest {
        attributes(
            "Main-Class" to "com.example.Application",
            "Implementation-Title" to project.name,
            "Implementation-Version" to project.version,
            "Built-By" to System.getProperty("user.name"),
            "Built-Date" to java.time.LocalDate.now()
        )
    }
    
    // 归档名称
    archiveBaseName.set("my-app")
    archiveVersion.set(project.version.toString())
    
    // 排除不需要的文件
    exclude("**/*.pem", "**/*.key")
}

Fat JAR(可执行 JAR,含所有依赖)

方式一:手动配置(不推荐)

kotlin
tasks.register<Jar>("fatJar") {
    archiveClassifier.set("all")
    manifest {
        attributes("Main-Class" to "com.example.Application")
    }
    
    from(sourceSets.main.get().output)
    
    dependsOn(configurations.runtimeClasspath)
    from(configurations.runtimeClasspath.get().filter { it.name.endsWith(".jar") }.map { zipTree(it) })
    
    duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}

方式二:Shadow 插件(推荐)

kotlin
plugins {
    id("com.github.johnrengelman.shadow") version "8.1.1"
    application
}

application {
    mainClass.set("com.example.Application")
}

tasks.named<com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar>("shadowJar") {
    archiveClassifier.set("")  // 默认为 "all"
    mergeServiceFiles()        // 合并 META-INF/services(SPI 需要)
    
    // 重定位(避免类名冲突)
    relocate("com.google.guava", "com.example.shadow.guava")
}
bash
./gradlew shadowJar
# 输出:build/libs/my-app-1.0.0.jar(含所有依赖)

# 运行
java -jar build/libs/my-app-1.0.0.jar

方式三:Spring Boot 插件(Spring 项目推荐)

kotlin
plugins {
    id("org.springframework.boot") version "3.2.0"
}

// Spring Boot 插件自动配置 bootJar 任务
tasks.named<org.springframework.boot.gradle.tasks.bundling.BootJar>("bootJar") {
    archiveFileName.set("my-app.jar")
    mainClass.set("com.example.Application")
    
    // 分层 JAR(加速 Docker 构建)
    layered {
        enabled.set(true)
    }
}
bash
./gradlew bootJar
java -jar build/libs/my-app.jar

Sources JAR

kotlin
// 方式一:java 插件简捷配置
java {
    withSourcesJar()
}

// 方式二:手动定义
tasks.register<Jar>("sourcesJar") {
    archiveClassifier.set("sources")
    from(sourceSets.main.get().allSource)
}

Javadoc JAR

kotlin
java {
    withJavadocJar()
}

tasks.named<Javadoc>("javadoc") {
    options.encoding = "UTF-8"
    (options as StandardJavadocDocletOptions).apply {
        addBooleanOption("html5", true)
        addStringOption("charset", "UTF-8")
    }
}

下一步