4

I've been struggling with selenium to fix this issue:

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

This is where I get this error:

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;
});

The most solutions on the internet suggest to use Guava 21, but this is not working for me.

Running selenium locally works just fine, and I don't get this issue, the problem is we use a runner that will use the selenium-server-standalone-3.12.0 to run tests on multiple virtual machines, and in the classpath we define all the dependencies we use, where I declared Guava as well, I also tried other versions of Guava from 19 to 23.

I tried multiple solutions and now I'm out of ideas, I don't know why I'm still getting this error even though I have declared Guava, and I can clearly see when I run tests locally, that Guava 23 works just fine.

I'm using java 1.8_71.

When I checked the code source of selenium-server-standalone-3.12.0 the Wait interface looks like this:

import java.util.function.Function;

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

But in local it looks like this:

import com.google.common.base.Function;

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

But since com.google.common.base.Function is extending com.google.common.base.Function in Guava 23, this shouldn't be a problem, so why I'm still getting this error ?

Thanks in advance.

Update:

I have checked the content of the standalone jar, and it contains Guava version 23.6-jre, so I'm highly skeptical about the issue being from guava.

I also checked the Wait interface and it's defined like this:

import java.util.function.Function;

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

I still don't understand why I'm getting until(Lcom/google/common/base/Function;) in the exception when the used Function interface is from java.util.function and not com.google.common.base

Update 2

I have somehow solved this issue by looking at how intellij executes my jar, so I added D:\..\target\test-classes to the classpath and the exception disappeared for some reason, why this happened ? and how can I include the files in test-classes to my final jar ?

Normally I have a bat file that runs my test:

@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 %*

which I use as following:

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

This won't work I'll get the NoSuchMethodError exception unless I add this to the class path:

@set CLASSPATH=%CLASSPATH%D:\sln\target\test-classes;
Community
  • 1
  • 1
Renaud is Not Bill Gates
  • 1,684
  • 34
  • 105
  • 191
  • What is your local Selenium version? – Guy Jan 16 '20 at 12:37
  • @Guy `selenium-server-standalone-3.12.0` – Renaud is Not Bill Gates Jan 16 '20 at 12:42
  • You are using the `selenium-server` locally? not only on the remote servers? I'm asking because up to Selenium version 3.1.0 `Wait` did use `com.google.common.base.Function;`. But server 3.12.0 use Selenium 3.12.0. – Guy Jan 16 '20 at 12:43
  • @Guy Yes I use selenium-server locally, I did the to use the same jars used in prod, but the problem is not when I'm running selenium in local but in prod – Renaud is Not Bill Gates Jan 16 '20 at 13:08
  • You can refer https://maven.apache.org/plugins/maven-jar-plugin/examples/create-test-jar.html or use Assembly plugin to have test classes in fat-jar – Rahul L Jan 20 '20 at 09:58
  • @IchigoKurosaki I want to know have you added guava jar from starting (before this error) OR you have added guava jar after this error? – Muzzamil Jan 20 '20 at 14:07

4 Answers4

4

This error message...

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

...implies that the Guava version was incompatible.


As you are using selenium-server-standalone-3.12.0 as per the contents of selenium-java-3.12.0 client kits the supported version is:

guava-23.6-jre


Snapshot

guava


Solution

An immediate solution would be to:

  • Upgrade Guava with guava-23.6-jre.jar

The real issue

In your first update as you have confirmed that Guava version is 23.6-jre, the real issue seems to be constructor of FluentWait. The argument type for withTimeout and pollingEvery post Selenium v3.11.0, which was:

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

Are now Deprecated and the new type is java.time.Duration. So your effective code block will be:

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

You can find a detailed discussion in The type FluentWait is not generic; it cannot be parameterized with arguments error for FluentWait Class through Selenium and Java


Additional Consideration

Additionally,

  • Your JDK version is 1.8_71 which is pretty old and ancient.
  • Solution: Ensure that JDK is upgraded to current levels JDK 8u222.

Best Practices

As per the best practices you need to:

  • Upgrade JDK to recent levels JDK 8u222.
  • Upgrade Selenium to current levels Version 3.141.59.
  • GeckoDriver and Firefox specific:
    • Upgrade GeckoDriver to GeckoDriver v0.26.0 level.
    • GeckoDriver is present in the desired location.
    • GeckoDriver is having executable permission for non-root users.
    • Upgrade Firefox version to Firefox v72.0 levels.
  • ChromeDriver and Chrome specific:
  • Clean your Project Workspace through your IDE and Rebuild your project with required dependencies only.
  • (WindowsOS only) Use CCleaner tool to wipe off all the OS chores before and after the execution of your Test Suite.
  • (LinuxOS only) Free Up and Release the Unused/Cached Memory in Ubuntu/Linux Mint before and after the execution of your Test Suite.
  • If your base Web Client version is too old, then uninstall it through Revo Uninstaller and install a recent GA and released version of Web Client.
  • Take a System Reboot.
  • Execute your Test as a non-root user.
  • Always invoke driver.quit() within tearDown(){} method to close & destroy the WebDriver and Web Client instances gracefully.

Reference

You can find a relevant detailed discussion in:

undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
  • Thanks for your answer, but unfortunately this didn't work for me, I have updated the version of JDK to to latest one `jdk1.8.0_231` as well as guava to `guava-23.6-jre.jar` but I'm still getting the same error – Renaud is Not Bill Gates Jan 14 '20 at 14:12
  • @IchigoKurosaki Checkout the updated answer and let me know the status. – undetected Selenium Jan 14 '20 at 14:19
  • yeah nothing seems to work, updated the java version, I cant upgrade or downgrade the selenium version, we are using `selenium-server-standalone-3.12.0` for multiple projects, GeckoDriver won't do anything in this case, I'm using chrome driver, which I can't also change, this issue has nothing to do with my IDE, it's in production where selenium-server-standalone is used – Renaud is Not Bill Gates Jan 14 '20 at 14:46
  • @IchigoKurosaki Can you remove all the Selenium related jars, close IDE (Eclipse), restart your machine, add back the required jars and execute your test again? – undetected Selenium Jan 20 '20 at 07:38
  • @IchigoKurosaki Take one more attempt, remove all the existing Selenium related jars, clean your _Project space_ within your IDE (Ecplise), add back the jars, re-compile and execute your test. – undetected Selenium Jan 23 '20 at 14:28
  • @IchigoKurosaki Possibly we have nailed the real issue. Checkout the **`The real issue`** section within the updated answer and let me know the status. – undetected Selenium Jan 23 '20 at 16:35
3

This is compatibility issue. To solve it, you can use Guava version 21 + selenium version 3.2.0 + JDK 8.

For more details you can check below link:

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

I hope it will help you.

Muzzamil
  • 2,823
  • 2
  • 11
  • 23
  • Unfortunately I can't change the version of selenium server, I have to use the version 3.12.0, I'll try the other provided solutions – Renaud is Not Bill Gates Jan 14 '20 at 13:15
  • @IchigoKurosaki I don't know when you have added Guava library to project (from begining or after this error). I have created a demo project to test it with same version of selenium-server-standalone, guava and java. I didn't find any error for 'Webdriver wait' but when I have added guava 19 and I got same error. I would say if you are using guava from beginning then you can remove Guava library and give it a try. – Muzzamil Jan 23 '20 at 09:36
0

Simple short answer: You have dependency issues with an outdated guava version!

-> Do this: In every single project explicitly exclude the guava dependency from every single dependency that requests it (use the dependency graph to find these) or better exclude it in the parent (if you have one)

-> Then add the guava 23.0 (or newer) dependency explicitly.

This will fix it. Right now from somewhere an old guava version is being pulled that doesnt have the "until" method (or at least not with this parameter).

Good Luck! :)

fl0w
  • 3,593
  • 30
  • 34
0

I think you should check under D:\sln\ and D:\sln\lib\ if there's any other version of selenium library in there. Delete it out if there's one.

From the error message, it seems like when you execute the batch script it use a different version of Selenium from a different selenium jar file. Probably the old version of selenium jar that haven't had the Wait.until method yet.

Montri M
  • 1,716
  • 14
  • 12