Java 是否可以检查哪个gradle依赖项包含给定的类?
最近,我们遇到了一个类Java 是否可以检查哪个gradle依赖项包含给定的类?,java,gradle,dependencies,dependency-management,Java,Gradle,Dependencies,Dependency Management,最近,我们遇到了一个类org.apache.commons.beanutils.PropertyUtilsBean的版本不匹配问题。我们认为不匹配只是在版本1.8和1.9.3中带来的commons beanutils之间的一些依赖,但是在跟踪并排除每个可传递依赖之后,我们仍然面临一个问题 事实证明,PropertyUtilsBean也被封装在commons-digester3-3.2-with-deps中,而不是声明为对commons beanutils的依赖关系 在gradle中是否可以搜索所
org.apache.commons.beanutils.PropertyUtilsBean
的版本不匹配问题。我们认为不匹配只是在版本1.8和1.9.3中带来的commons beanutils
之间的一些依赖,但是在跟踪并排除每个可传递依赖之后,我们仍然面临一个问题
事实证明,PropertyUtilsBean也被封装在commons-digester3-3.2-with-deps
中,而不是声明为对commons beanutils
的依赖关系
在gradle中是否可以搜索所有依赖项(包括可传递的依赖项)以查找特定的完全限定类名?这样我们就可以当场解决此类问题。只需按住ctrl键并左键单击导入的类名,然后您就可以在ide上看到jar(eclipse具有该功能,可能IntelliJ也具有该功能)尝试使用以下任务:
每个Gradle项目都提供任务依赖性Insight来呈现
来自命令行的所谓依赖性洞察报告。给予
依赖关系在依赖关系图中,您可以标识所选内容
推理并跟踪依赖项选择的来源
我试过了,可以使用一些定制的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())
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) {}
}
}
}
}
这可以通过使用一些参数机制替换硬编码的类名来进一步增强
样本输出:
> 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
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())
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) {}
}
}
}
}
你可以这样做
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}"
}
}
这就是我们找到它的方式,但我很好奇是否有Gradle特定的解决方案。在这种情况下,我想在任何依赖项中寻找特定的类。类似于
yum提供的
这似乎很有希望,但您在这里使用的是什么语言呢?是Gradle-Kotlin DSL。也可以使用Groovy实现。我还添加了一个基于Goovy的示例