是否可以检查哪个gradle依赖项包含给定的类?

时间:2018-04-06 11:48:11

标签: 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中搜索特定完全限定类名的所有依赖项(包括传递依赖项)?这样我们就可以当场解决这些问题。

4 个答案:

答案 0 :(得分:4)

我尝试过,可以使用一些自定义的gradle构建逻辑:

科特林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) {}
        }
    }
  }
}

答案 1 :(得分:3)

您可以这样做

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}"
   } 
}

答案 2 :(得分:2)

只需 ctrl +左键单击已导入的类名,然后你可以看到你的ide上的jar(eclipse有这个功能,可能还有IntelliJ)

答案 3 :(得分:0)

尝试使用任务dependencyInsight

gradle -q dependencyInsight --configuration compile --dependency commons-beanutils
  

每个Gradle项目都提供任务dependencyInsight来呈现   来自命令行的所谓依赖性洞察报告。给出一个   依赖关系图中的依赖关系可以识别选择   推理并追踪依赖选择的起源。