我是靠谱客的博主 无奈溪流,最近开发中收集的这篇文章主要介绍【难题已解决】gradle 如何排除一个jar依赖(即files形式的本地依赖)中的依赖(如slf4j)?,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

文章目录

    • 前言
    • 正文
      • 1、源代码片段
      • 2、删掉或者禁用掉gumtree.jar的日志依赖
    • 小结
    • 参考文献

前言

创作开始时间:2021年3月14日16:20:14

本文旨在解决困扰我许久的问题:gradle项目中有一个本地依赖(jar包),但是这个jar包中呢又包含了其所有依赖(包括烦人的slf4j日志依赖),这样我自己的gradle项目在运行的时候,就会报错:SLF4J: Class path contains multiple SLF4J bindings. 我真的最烦这种错误了。所以我想把这个依赖jar包中的slf4j包给exclude掉。

但是呢,gradle不支持对files("xxx.jar")调用exclude group的语法!所以,一番探索之后,才找到解决方案,这里记录之。

正文

1、源代码片段

我项目长这样:
tree -L 2
在这里插入图片描述

我的build gradle文件内容片段如下:

// gumtree依赖
implementation files('/home/xxx/GumTree_repos/gumtree/dist/build/libs/gumtree.jar')

// for logging 日志依赖
compile "org.slf4j:slf4j-log4j12:1.7.25"
compile "org.slf4j:slf4j-api:1.7.25" 

gumtree原仓库网址:https://github.com/GumTreeDiff/gumtree/

gumtree项目的子模块client.diff的build.gradle文件包含日志依赖:

implementation 'org.slf4j:slf4j-simple:1.7.21'

以上环境已经讲清楚了。
我的项目依赖于gumtree.jar(3.0.0-beta1版本),同时我也定义了自己的日志依赖;但是gumtree.jar 有自己的日志依赖;所以就冲突啦。

我现在想删掉或者禁用掉gumtree.jar的日志依赖。

2、删掉或者禁用掉gumtree.jar的日志依赖

1)先查看gumtree项目所在目录下打包后的jar包dist/build/libs/gumtree.jar,确实包含了slf4j日志依赖:

在这里插入图片描述

2)找到gumtree项目所在的子模块client.diff的build.gradle,将其中的implementation 'org.slf4j:slf4j-simple:1.7.21' 修改为如下:

//implementation 'org.slf4j:slf4j-simple:1.7.21'
	// dale:
	compileOnly 'org.slf4j:slf4j-simple:1.7.21'

3)在gumtree项目下重新编译打包:

./gradlew build -x test

4)然后查看重新打包后的gumtree.jar:
可以看到slf4j中的impl包终于消失了!

在这里插入图片描述
5)重新运行我的项目,发现再也没有报错信息了:

SLF4J: Class path contains multiple SLF4J bindings.

可以了。

小结

其实花了很多时间。这方面文献确实少,Stack Overflow上都没有找到解决方案。

最后看多了网页之后,大概自己琢磨出来的。

总算搞好了。

其实还有几种方案可行:

  1. 修改gumtree 中的build.gradle 中有关shadowJar的参数配置,我觉得是可行的
  2. 删除gumtree中的shadowJar,不让其打包所有依赖,而是分开打包,然后就可以手动删除jar了。这样应该也可以的。

时间关系,不一一去尝试了。

创作结束时间:2021年3月14日16:58:42

参考文献

  • Exclude module dependencies from jar file in gradle
    这个真是关键,当头棒喝。gradle内根本不支持exclude 本地依赖中的依赖。所以启发我不得不另寻出路,从本地依赖本身找方案。

在这里插入图片描述

  • How to exclude modules or groups in a jar from Gradle?
    这个同样关键,也是说只能从本地依赖中入手,但是这里说的解压jar然后重新打包,我试了,没啥用。不好用。所以最后采取重新编译的方法。
    在这里插入图片描述

  • gradle中compile、api、provided、implementation

  • gradle4.1以上compile,provided废弃了
    可以用provided参数。
    但是被淘汰了,需要用compileOnly

  • gradle compileOnly的使用场景

编译时仅需要其API,但具体实现由别的module实现
所以 compileOnly经常用于解决依赖冲突等问题,一般第三方库中,比较常用的依赖,如support、gson、Eventbus等等。

正合我意。

——————————————————————————————

  • Gradle - Exclude file from being packaged with jar

有点创意的:

jar {     
   exclude('your thing')     
}

以下22篇文献都是我为了解决这个问题看的,真是头晕眼花。
这就是解决问题的过程吧,一开始什么都不懂,什么都去试,可以看看我做的尝试:

/*
	implementation fileTree(dir: "/home/xxx/xxx/GumTree_repos/gumtree/dist/build/libs/", includes: ['*.jar']) 
	 {
   		exclude group: 'org.slf4j'
	}
	*/
	/*{
		exclude "org.slf4j:slf4j-log4j12:21"
	}*/
	
	
	implementation files('/home/xxx/gumtree/dist/build/libs/gumtree.jar')
	
	//implementation (files('/home/xxx/gumtree/dist/build/libs/gumtree.jar'))
	/*
	{
		//exclude group: 'org.slf4j:slf4j-simple:1.7.21'
		//exclude group: 'org.slf4j', module:'slf4j-simple:1.7.21'
		//exclude  module:'org.slf4j:slf4j-simple:1.7.21'
		//, module:'slf4j-simple'
		//transitive = false
	}
	*/
	
	/*
	{
    	exclude group: 'org.slf4j'
	}
	*/
	/*
	{
	transitive = false
   		
	}
	*/

很多都没用。
但是也加深了我对gradle的理解,和问题本身的理解。最后还是搞定了。
感悟颇深,不一一记录了。(且有时候看了一段时间没结果,还需要跳出来,再进去问题本身思考。)

  1. Could not find method exclude() for arguments [{module=support-v4}]
  2. Could not find method exclude() for arguments on object of type org.gradle.api.internal.artifacts.dependencies.DefaultSelfResolvingDependency
  3. Could not find method compile() for arguments Gradle
  4. Could not find method implementation () for arguments [directory ‘libs’] on object of type org.gradle.api.internal.artifacts.dsl.dependencies
  5. Exclude files from FileTree in Gradle
  6. Gradle fileTree exclude all except certain directories
  7. how to exclude jar from fileTree in upstream projects?
  8. How to exclude modules or groups in a jar from Gradle?
  9. Gradle: How to make a compile scope file dependency excluded in packaging?
  10. How to exclude transitive jar dependency in Gradle?
  11. Interface ModuleDependency
  12. Exclude file from jar using Gradle
  13. Exclude duplicate log4j binding from transitive dependency contained in built-in plugin #271
  14. How can I exclude a dependency from another dependency?
  15. How to exclude libraries from all dependencies in Gradle
  16. Downgrading versions and excluding dependencies
  17. How to exclude multiple SLF4J bindings to LOG4J
  18. Class path contains multiple SLF4J bindings error
  19. Using gradle to find dependency tree
  20. Suppress SLF4J Multiple Bindings Gradle
  21. how to properly configure gradle build to avoid including log4j and slf4j from the resulting jar?
  22. Eclipse- How to remove jars which are added “from class path” of referenced library

——————————————————————————————

  • Gradle 依赖&解决依赖冲突
  • 带你一文搞清 Gradle 依赖,纯干货汇总!

最后

以上就是无奈溪流为你收集整理的【难题已解决】gradle 如何排除一个jar依赖(即files形式的本地依赖)中的依赖(如slf4j)?的全部内容,希望文章能够帮你解决【难题已解决】gradle 如何排除一个jar依赖(即files形式的本地依赖)中的依赖(如slf4j)?所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(74)

评论列表共有 0 条评论

立即
投稿
返回
顶部