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是否可以在所有依赖项(包括可传递的依赖项)中搜索特定的完全限定的类名?这样,我们可以当场解决此类问题。
我试过了,可以使用一些自定义的 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)
你可以这样做
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也有)
| 归档时间: |
|
| 查看次数: |
607 次 |
| 最近记录: |