Gradle如何决定从哪个依赖项中获取类(如果它存在于多个依赖项中)



我使用Gradle,在我的项目中有两个依赖项:

implementation group: 'org.seleniumhq.selenium', name: 'selenium-api', version: '3.1.4'
implementation group: 'io.appium', name: 'java-client', version: '5.0.2'

两个依赖项在同一个包下都有一个WebDriver类:

org.openqa.selenium.WebDriver

尽管build.gradle文件中这两个依赖项的顺序不同,但当我使用WebDriver时,引用指向第二个依赖项-java客户端。

Gradle如何决定使用哪个依赖项?如果我注释掉java客户端,那么引用将转到另一个客户端(seleniumApi——我希望使用的那个(。

摆弄java客户端的版本显示出更令人困惑的结果:

  • 在使用版本低于4.1.0的WebDriver时,可以通过seleniumApi正确解析类依赖关系
  • 在使用4.1.0及更高版本时,它被解析为java客户端

我不明白这里的规则是什么。或者,在这种情况下,我如何指定解决策略?

问题不在于构建工具及其依赖性解决方案。从Gradle的角度来看,这些依赖关系没有任何共同点,而是独立解决的。

每个依赖项都会成为运行时类路径中的一个条目,因此使用哪一个类只是类路径顺序的问题,这通常是个坏主意。

不同于版本的两个不同的库工件不应该提供相同的类——除非你真的想替换它,并且永远不能像SLF4J包装器那样一起使用。相反,他们应该更改包结构(请参阅Apache Commons Lang,例如,将包org.Apache.Commons.Lang移动到导入org.Apache.communs.lang3,以避免在包含可传递依赖项或预包装类时发生冲突(。

在这种情况下,Appium在包含Selenium类而不是声明传递依赖关系方面做得很糟糕。您不应该在一个项目模块中同时使用这两个依赖项,否则会得到不可预测的结果,尤其是在selenium类的实现不同的情况下。据我所知,这个问题已经在Appium的后续版本中得到了解决,请尝试升级到版本7而不是5。

最新更新