如何通过Gradle从IDEA插件中排除slf4j Jar包
问题背景
我正在开发一款IDEA插件,编译过程一切正常,但启动沙箱时遇到了SLF4J绑定冲突的问题,错误日志如下:
SLF4J: Found binding in [jar:file:/home/kamil/projects/tx/build/idea-sandbox/plugins/modif-tx/lib/tx-slf4j-2018.1.0.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/home/kamil/.gradle/caches/modules-2/files-2.1/com.jetbrains.intellij.idea/ideaIC/2018.1/d082978a55b398ef544e7daee1dd6228b88dbfc1/ideaIC-2018.1/lib/slf4j-log4j12-1.7.10.jar!/org/slf4j/impl/StaticLoggerBinder.class]
我希望从IDEA插件的打包结果中排除自带的SLF4J Jar包,避免和IDEA沙箱本身的SLF4J实现冲突,请问如何通过Gradle配置实现?
解决方案
针对这个问题,你可以通过Gradle的依赖排除机制,结合IDEA插件开发的特殊配置来解决,下面是几种实用的方式:
1. 单个依赖中排除SLF4J
如果你的插件依赖里只有某个特定库引入了SLF4J,直接在该依赖的声明里添加排除规则即可:
dependencies { implementation('your.group:your-dependent-library:your-version') { // 排除SLF4J的API和具体实现模块,根据实际引入的模块调整名称 exclude group: 'org.slf4j', module: 'slf4j-api' exclude group: 'org.slf4j', module: 'slf4j-log4j12' } }
2. 全局排除所有SLF4J依赖
如果多个依赖都引入了SLF4J,逐个配置太麻烦,你可以在configurations块里全局排除:
configurations { all { exclude group: 'org.slf4j', module: 'slf4j-api' exclude group: 'org.slf4j', module: 'slf4j-log4j12' // 如果还有其他SLF4J相关模块,比如slf4j-simple,也可以在这里添加排除 } }
3. 利用IDEA Gradle插件的provided依赖配置
如果你用的是JetBrains官方的gradle-intellij-plugin,最推荐的方式是把SLF4J标记为IDE提供的依赖——这样Gradle会在编译时使用它,但不会把它打包进插件:
intellij { version '2018.1' // 对应你使用的IDE版本 plugins 'java' // 你的插件依赖的IDE插件 // 声明SLF4J为IDE提供的依赖,不打包到插件中 providedDependencies 'org.slf4j:slf4j-api:1.7.10' providedDependencies 'org.slf4j:slf4j-log4j12:1.7.10' }
验证配置是否生效
修改完配置后,先执行./gradlew clean build清理并重新编译项目,然后检查build/idea-sandbox/plugins/modif-tx/lib目录,确认tx-slf4j-2018.1.0.jar已经消失,再启动沙箱就能避免SLF4J绑定冲突了。
内容的提问来源于stack exchange,提问作者Kamil Xovitz

