是否可以检查哪些 gradle 依赖项包含给定的类?
Posted
技术标签:
【中文标题】是否可以检查哪些 gradle 依赖项包含给定的类?【英文标题】:Is it possible to check which gradle dependencies contains given class? 【发布时间】:2018-09-16 10:37:10 【问题描述】:最近我们遇到了 org.apache.commons.beanutils.PropertyUtilsBean
类的版本不匹配问题。我们认为不匹配只是在版本 1.8 和 1.9.3 中带来 commons-beanutils
的某些依赖项之间,但在跟踪并排除每个传递依赖项之后,我们仍然面临一个问题。
事实证明,PropertyUtilsBean 也被打包在 commons-digester3-3.2-with-deps
中,而不是声明为对 commons-beanutils
的依赖。
是否可以在 gradle 中搜索所有依赖项(包括传递的依赖项)以查找特定的完全限定类名?这样我们就可以当场解决这些问题。
【问题讨论】:
【参考方案1】:我试过了,可以使用一些自定义的 gradle 构建逻辑:
Kotlin DSL
tasks
val searchClass by creating
doLast
configurations.forEach // check all configurations
if (it.isCanBeResolved)
try
val classLoader = configToClassloader(it)
// replace here class you are looking for
val cl = Class.forName("arrow.core.Either", false, classLoader)
println("found in Configuration $it")
println(cl.protectionDomain.codeSource.location)
catch (e: Exception)
// Helper function: convert a gradle configuration to ClassLoader
fun configToClassloader(config: Configuration) =
URLClassLoader(
config.files.map
it.toURI().toURL()
.toTypedArray())
这可以通过用一些参数机制替换硬编码的类名来进一步增强。
样本输出:
> Task :searchClass
Configuration configuration ':domain:apiDependenciesMetadata'
file:/Users/abendt/.gradle/caches/modules-2/files-2.1/io.arrow-kt/arrow-core-data/0.9.0/a5b0228eebd5ee2f233f9aa9b9b624a32f84f328/arrow-core-data-0.9.0.jar
Groovy DSL
def configToClassloader(config)
return new URLClassLoader(
*config.files.collect
it.toURI().toURL()
.toArray())
task searchClass
doLast
configurations.forEach // check all configurations
if (it.canBeResolved)
try
def classLoader = configToClassloader(it)
// replace here class you are looking for
def cl = Class.forName("arrow.core.Either", false, classLoader)
println("found in Configuration $it")
println(cl.protectionDomain.codeSource.location)
catch (e)
编辑:我最近创建了一个提供所描述任务的 Gradle 插件:https://plugins.gradle.org/plugin/io.github.redgreencoding.findclass
【讨论】:
这看起来很有希望,但是您在这里使用的是什么语言? 这是 Gradle Kotlin DSL。也可以使用 Groovy 来实现 我也添加了一个基于 Goovy 的示例【参考方案2】:你可以这样做
task findJarsForClass
doLast
def findMe = 'org/apache/commons/beanutils/PropertyUtilsBean.class'
def matches = configurations.runtime.findAll f ->
f.name.endsWith('.jar') &&
!(zipTree(f).matching include findMe .empty)
println "Found $findMe in $matches*.name"
【讨论】:
【参考方案3】:只需ctrl+左键点击导入的类名,就可以在ide上看到jar了(eclipse有这个功能,可能IntelliJ也有)
【讨论】:
这就是我们找到它的方式,但我很好奇是否有 Gradle 特定的解决方案。【参考方案4】:尝试使用任务dependencyInsight
:
gradle -q dependencyInsight --configuration compile --dependency commons-beanutils
每个 Gradle 项目都提供了 task dependencyInsight 来渲染 来自命令行的所谓依赖洞察报告。给定一个 依赖关系图中的依赖关系,您可以识别选择 原因并追踪依赖选择的来源。
【讨论】:
在这种情况下,我想在任何依赖项中查找特定类。类似yum provides
以上是关于是否可以检查哪些 gradle 依赖项包含给定的类?的主要内容,如果未能解决你的问题,请参考以下文章
使用变量时如何在 build.gradle 中查看依赖项更新?
是否可以让 gradle 解析像 '5.0.+' 这样的 ivy 依赖项以获得像 '5.0.0.1.12.24' 这样的版本?