You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Gradle插件开发:瘦包可用但构建胖包后插件无法被消费项目识别

搞定Gradle插件Fat Jar后找不到插件的问题

嘿,我太懂这种前后矛盾的崩溃感了——一开始插件没带依赖报NoClassDefFoundError,好不容易打了Fat Jar,结果连插件本身都找不到了!核心问题出在你的Fat Jar配置破坏了Gradle识别自定义插件的关键机制。

先给你说清楚原因:Gradle能找到my.custom.plugin这个ID,全靠插件Jar里的META-INF/gradle-plugins/my.custom.plugin.properties文件,这个文件里写着插件实现类的全路径。你之前的Jar配置直接把所有依赖Jar解压合并,要么是把自己插件的这个关键文件给覆盖了,要么就是压根没把它正确打包进去。

下面给你两个靠谱的解决方案,优先推荐第一个,毕竟是Gradle官方的路子:

方案1:用官方java-gradle-plugin插件(省心首选)

Gradle专门给自定义插件开发做了java-gradle-plugin插件,它会自动帮你处理插件声明、依赖打包,还能生成正确的元数据,完全不用自己瞎折腾Jar任务。

修改你的plugin/build.gradle:

plugins {
    id 'java-gradle-plugin'
    // 如果需要纯正的Fat Jar,再加个shadow插件
    id 'com.github.johnrengelman.shadow' version '8.1.1'
}

// 核心:声明你的插件ID和对应的实现类
gradlePlugin {
    plugins {
        customPlugin {
            id = 'my.custom.plugin'
            // 替换成你自己插件实现类的全路径,比如com.yourteam.MyPlugin
            implementationClass = '你的插件实现类全路径'
        }
    }
}

// 配置shadowJar生成Fat Jar,保留插件元数据
shadowJar {
    archiveBaseName.set("plugin-all")
    archiveClassifier.set("") // 去掉默认的shadow后缀,方便引用
    mergeServiceFiles()
    // 确保插件的元数据不被覆盖
    mergeManifest {
        attributes 'Implementation-Title': '我的自定义Gradle插件',
                   'Implementation-Version': project.version
    }
}

// 让build任务自动触发shadowJar,构建完直接生成Fat Jar
build.dependsOn(shadowJar)

然后在plugin_consumer里,把依赖指向生成的Fat Jar就行:

buildscript {
    repositories {
        // 你的仓库配置
    }
    dependencies {
        classpath fileTree(dir:'../plugin/build/libs', include: ['plugin-all.jar'])
    }
}

apply plugin: 'my.custom.plugin'

方案2:修复你原来的Fat Jar配置

要是你不想换插件,那得调整Jar任务,确保自己插件的元数据不被依赖覆盖:

修改plugin/build.gradle的Jar配置:

jar {
    archiveName = 'plugin.jar'
    baseName = project.name + '-all'
    
    // 先把插件自己的代码和元文件打包进去(这步你之前可能漏了!)
    from sourceSets.main.output
    
    // 再添加依赖,但要排除依赖里的Gradle插件元文件,防止覆盖自己的
    from {
        configurations.compileClasspath.collect {
            it.isDirectory() ? it : zipTree(it).matching {
                exclude 'META-INF/gradle-plugins/**'
                exclude 'META-INF/*.properties' // 按需排除,避免冲突
            }
        }
    }
    
    // 遇到重复文件时,优先保留自己的
    duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}

这里的关键是先打包自己的代码和元文件,再添加依赖,同时排除依赖里可能干扰的META-INF文件,不然依赖里如果有其他Gradle插件,会把你的插件声明给冲掉。

为啥原来的配置会炸?

你之前的Jar任务直接把所有依赖解压合并,要是某个依赖Jar里也有META-INF/gradle-plugins下的文件,就会把你自己的my.custom.plugin.properties给覆盖了,Gradle自然找不到你的插件。另外,你没明确把插件自身的编译输出加进去,搞不好连插件核心代码都没打包进去,可不就找不到嘛!


内容的提问来源于stack exchange,提问作者Ben

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:03:18