java.lang.NoSuchMethodError: org.openqa.selenium.support.ui.Wait.until(Lcom/google/common/base/Funct

Posted

技术标签:

【中文标题】java.lang.NoSuchMethodError: org.openqa.selenium.support.ui.Wait.until(Lcom/google/common/base/Function;) 使用 selenium-server-standalone-3.12.0【英文标题】:java.lang.NoSuchMethodError: org.openqa.selenium.support.ui.Wait.until(Lcom/google/common/base/Function;) using selenium-server-standalone-3.12.0 【发布时间】:2020-05-01 02:32:47 【问题描述】:

我一直在用 selenium 来解决这个问题:

java.lang.NoSuchMethodError: org.openqa.selenium.support.ui.Wait.until(Lcom/google/common/base/Function;)Ljava/lang/Object;

这是我得到这个错误的地方:

Wait<WebDriver> wait = new FluentWait<>(getDriverInstance())
        .withTimeout(timeout, TimeUnit.SECONDS)
        .pollingEvery(frequency, TimeUnit.SECONDS)
        .ignoring(NoSuchElementException.class);
wait.until(driver -> 
    assert driver != null;
    elt.click();
    return true;
);

互联网上的大多数解决方案建议使用Guava 21,但这对我不起作用。

在本地运行 selenium 工作得很好,我没有遇到这个问题,问题是我们使用了一个运行器,它将使用 selenium-server-standalone-3.12.0 在多个虚拟机上运行测试,并且在类路径中我们定义了所有依赖项我们使用,在我声明 Guava 的地方,我还尝试了其他版本的 Guava 从 19 到 23。

我尝试了多种解决方案,但现在我没有想法,我不知道为什么即使我已经声明了 Guava,我仍然会收到此错误,并且当我在本地运行测试时,我可以清楚地看到 @987654327 @ 工作得很好。

我正在使用 java 1.8_71

查看selenium-server-standalone-3.12.0的代码源,Wait界面如下:

import java.util.function.Function;

public interface Wait<F> 
    <T> T until(Function<? super F, T> var1);

但在本地看起来像这样:

import com.google.common.base.Function;

public interface Wait<F> 
    <T> T until(Function<? super F, T> var1);

但是由于 com.google.common.base.Function 在 Guava 23 中扩展了 com.google.common.base.Function,这应该不是问题,那为什么我仍然会收到此错误?

提前致谢。

更新:

我检查了独立 jar 的内容,它包含 Guava 版本 23.6-jre,所以我非常怀疑这个问题来自番石榴。

我还检查了Wait 接口,它的定义如下:

import java.util.function.Function;

public interface Wait<F> 
    <T> T until(Function<? super F, T> var1);

当使用的Function 接口来自java.util.function 而不是com.google.common.base 时,我仍然不明白为什么我在异常中得到until(Lcom/google/common/base/Function;)

更新 2

我通过查看 intellij 如何执行我的 jar 以某种方式解决了这个问题,所以我在类路径中添加了 D:\..\target\test-classes 并且异常由于某种原因消失了,为什么会这样?以及如何将test-classes 中的文件包含到我的最终 jar 中?

通常我有一个运行我的测试的 bat 文件:

@SETLOCAL
@ECHO OFF
@set JAVA_HOME="C:\Program Files\Java\jdk1.8.0_231"
@set PATH=%JAVA_HOME%\bin;D:\drivers;%PATH%


@set CLASSPATH=.;
@set CLASSPATH=%CLASSPATH%D:\sln\lib\*;
@set CLASSPATH=%CLASSPATH%D:\sln\selenium-server-standalone-3.12.0.jar;

echo %CLASSPATH%
"C:\Program Files\Java\jdk1.8.0_231\bin\java.exe" com.sln.Runner %*

我使用如下:

D:\sln\Run.bat -u localhost -f D:\sln\target\sln-1.0-SNAPSHOT-tests.jar -c com.sln.SeleniumTest ...

这不起作用我会得到NoSuchMethodError 异常,除非我将它添加到类路径中:

@set CLASSPATH=%CLASSPATH%D:\sln\target\test-classes;

【问题讨论】:

你本地的 Selenium 版本是什么? @Guy selenium-server-standalone-3.12.0 您在本地使用selenium-server?不仅在远程服务器上?我问是因为直到 Selenium 版本 3.1.0 Wait 确实使用了 com.google.common.base.Function;。但是服务器 3.12.0 使用 Selenium 3.12.0。 @Guy 是的,我在本地使用 selenium-server,我这样做是为了使用与 prod 中相同的 jar,但问题不在于我在本地运行 selenium,而是在 prod 中运行 你可以参考maven.apache.org/plugins/maven-jar-plugin/examples/…或者使用Assembly插件在fat-jar中有测试类 【参考方案1】:

此错误消息...

java.lang.NoSuchMethodError: org.openqa.selenium.support.ui.Wait.until(Lcom/google/common/base/Function;)Ljava/lang/Object;

...暗示 Guava 版本不兼容。


当您使用 selenium-server-standalone-3.12.0 时,根据 selenium-java-3.12.0 客户端套件的内容,支持的 guava 版本是:

guava-23.6-jre


快照


解决方案

一个直接的解决方案是:

使用 guava-23.6-jre.jar 升级 Guava

真正的问题

在您确认 Guava 版本是 23.6-jre 的第一次更新中,真正的问题似乎是 FluentWait 的构造函数。 withTimeoutpollingEvery post Selenium v​​3.11.0 的参数类型,即:

pollingEvery: pollingEvery(long duration, java.util.concurrent.TimeUnit unit) withTimeout: withTimeout(long duration, java.util.concurrent.TimeUnit unit)

现已弃用,新类型为java.time.Duration。所以你的有效代码块将是:

Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.withTimeout(Duration.ofSeconds(30))
.pollingEvery(Duration.ofMillis(500))
.ignoring(NoSuchElementException.class);

您可以在The type FluentWait is not generic; it cannot be parameterized with arguments error for FluentWait Class through Selenium and Java找到详细讨论


其他注意事项

另外,

您的 JDK 版本1.8_71,相当古老。 解决方案:确保将 JDK 升级到当前级别JDK 8u222。

最佳实践

根据您需要的最佳实践:

JDK 升级到最新级别 JDK 8u222。 将Selenium升级到当前级别Version 3.141.59。 GeckoDriverFirefox 特定: 将GeckoDriver升级到GeckoDriver v0.26.0级别。 GeckoDriver 位于所需位置。 GeckoDriver 对非 root 用户具有可执行权限。 将 Firefox 版本升级到 Firefox v72.0 级别。 ChromeDriverChrome 具体: ChromeDriver 已更新到当前的ChromeDriver v79.0.3945.36 级别。 Chrome 已更新至当前 Chrome 版本 79.0 级别。 (根据ChromeDriver v79.0 release notes) 清理你的项目工作区通过你的IDE重建你的项目只需要依赖。 (仅限 Windows 操作系统)使用 CCleaner 工具在执行您的测试套件之前和之后清除所有操作系统琐事。 (仅限 LinuxOS)Free Up and Release the Unused/Cached Memory in Ubuntu/Linux Mint 在执行您的测试套件之前和之后。 如果您的基础 Web Client 版本太旧,请通过Revo Uninstaller 卸载它并安装最新的 GA 和发布版本的 Web Client。 进行系统重启。 以非 root 用户身份执行 Test。 始终在 tearDown() 方法中调用 driver.quit() 以优雅地关闭和销毁 WebDriverWeb Client 实例。

参考

您可以在以下位置找到相关的详细讨论:

org.openqa.selenium.remote.service.DriverService$Builder.createArgs()Lcom/google/common/collect/ImmutableList; with Selenium 3.5.3 Chrome 76

【讨论】:

感谢您的回答,但不幸的是,这对我不起作用,我已将 JDK 的版本更新为最新版本 jdk1.8.0_231 以及将番石榴更新为 guava-23.6-jre.jar 但我仍然得到同样的错误 @IchigoKurosaki 查看更新的答案并告诉我状态。 是的,似乎没有任何效果,更新了 java 版本,我无法升级或降级 selenium 版本,我们将selenium-server-standalone-3.12.0 用于多个项目,GeckoDriver 在这种情况下不会做任何事情,我' m 使用 chrome 驱动,我也无法更改,这个问题与我的 IDE 无关,它在使用 selenium-server-standalone 的生产环境中 @IchigoKurosaki 你能删除所有与 Selenium 相关的 jar,关闭 IDE (Eclipse),重新启动机器,添加回所需的 jar 并再次执行测试吗? @IchigoKurosaki 再试一次,删除所有现有的与 Selenium 相关的 jar,清理 IDE (Ecplise) 中的 Project space,重新添加 jar,重新编译并执行你的测试。【参考方案2】:

这是兼容性问题。要解决它,可以使用Guava 21 版 + selenium 3.2.0 版 + JDK 8

更多详情,您可以查看以下链接:

https://softwaretestingboard.com/q2a/1907/function-webdriver-fluentwait-webdriver-applicable-arguments#axzz68BFzmEjv

希望对你有帮助。

【讨论】:

很遗憾selenium server的版本无法更改,我必须使用3.12.0版本,我会尝试其他提供的解决方案 @IchigoKurosaki 我不知道您何时将 Guava 库添加到项目中(从开始或在此错误之后)。我创建了一个演示项目来使用相同版本的 selenium-server-standalone、guava 和 java 对其进行测试。我没有发现“Webdriver wait”有任何错误,但是当我添加了 guava 19 时,我得到了同样的错误。我想说如果你从一开始就使用番石榴,那么你可以删除番石榴库并试一试。【参考方案3】:

简单的简短回答:过时的 guava 版本存在依赖性问题!

-> 这样做: 在每个单独的项目中明确排除 guava 依赖项每个单独的依赖项 请求它(使用 依赖关系图 找到这些) 或者最好将它排除在父级中(如果你有的话)

-> 然后显式添加 guava 23.0(或更高版本) 依赖项。

这将解决它。现在正在从某个地方拉出一个旧的番石榴版本,它没有“直到”方法(或者至少没有这个参数)。

祝你好运! :)

【讨论】:

【参考方案4】:

我认为你应该检查D:\sln\D:\sln\lib\ 下是否有任何其他版本的硒库。有的话就删掉。

从错误消息看来,当您执行批处理脚本时,它似乎使用了来自不同 selenium jar 文件的不同版本的 Selenium。可能是老版本的 selenium jar 还没有 Wait.until 方法。

【讨论】:

以上是关于java.lang.NoSuchMethodError: org.openqa.selenium.support.ui.Wait.until(Lcom/google/common/base/Funct的主要内容,如果未能解决你的问题,请参考以下文章