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

lit*_*erg 10 java dependencies dependency-management gradle

最近,我们遇到了类的版本不匹配问题org.apache.commons.beanutils.PropertyUtilsBean。我们认为不匹配只是commons-beanutils引入1.8和1.9.3版本的某些依赖项之间的不匹配,但是在跟踪并排除每个传递性依赖项之后,我们仍然面临一个问题。

事实证明,PropertyUtilsBean也打包在commons-digester3-3.2-with-deps而不是声明为的依赖项内commons-beanutils

gradle是否可以在所有依赖项(包括可传递的依赖项)中搜索特定的完全限定的类名?这样,我们可以当场解决此类问题。

abe*_*ndt 6

我试过了,可以使用一些自定义的 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())
Run Code Online (Sandbox Code Playgroud)

这可以通过用一些参数机制替换硬编码的类名来进一步增强。

示例输出:

> 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   
Run Code Online (Sandbox Code Playgroud)

常规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) {}
        }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)


lan*_*ava 5

你可以这样做

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}"
   } 
}
Run Code Online (Sandbox Code Playgroud)


小智 2

只需ctrl+左键单击导入的类名,然后您就可以在您的IDE中看到该jar(eclipse有该功能,可能IntelliJ也有)

  • 这就是我们找到它的方式,但我很好奇是否有 Gradle 特定的解决方案。 (2认同)