Duplicate classes in different Java libraries leads to compilation errors Duplicate classes in different Java libraries leads to compilation errors selenium selenium

Duplicate classes in different Java libraries leads to compilation errors


The problem are not duplicate classes but the way generics are used. Here is a little MCVE replicating the situation in Appium's WebDriver class:

package de.scrum_master.stackoverflow;public interface WebElement {}
package de.scrum_master.stackoverflow;public interface WebDriver {  <T extends WebElement> T findElement();}
package de.scrum_master.stackoverflow;public class Application {  static WebDriver webDriver;  static void myOverloadedMethod(String text) {}  static void myOverloadedMethod(WebElement text) {}  public static void main(String[] args) {    // These 3 variants work    myOverloadedMethod("test");    myOverloadedMethod((WebElement) webDriver.findElement());    WebElement webElement = webDriver.findElement();    myOverloadedMethod(webElement);    // This one does not work    myOverloadedMethod(webDriver.findElement());  }}

Explanation: Due to type erasure doSomething's generic return type <T extends WebElement> evaluates to Object, so when trying to use that result for calling myOverloadedMethod(..) the compiler does not know which method to select.

Solution: You need to help by casting or explicitly declaring a type for a variable containing the method parameter.

P.S.: If you would modify the interface definition from interface WebDriver to interface WebDriver<T>, the compilation error would go away. But Appium's implementation does not do that, maybe because they want to stay as compatible(?) as possible to the original Selenium class. You have to ask them.


Update: Because the OP seems to have problems understanding my answer or to believe I did not try his sample code, which of course I used to reproduce and understand his problem:

package de.scrum_master.appium;import org.openqa.selenium.By;import org.openqa.selenium.WebDriver;import org.openqa.selenium.WebElement;public class Interactions {  public static void touchWebElement(WebElement element, WebDriver driver) {}  public static void touchWebElement(By by, WebDriver driver) {    // Works    WebElement webElement = driver.findElement(by);    touchWebElement(webElement, driver);    // Works    touchWebElement((WebElement) driver.findElement(by), driver);    // Ambiguous due to type erasure -> does not work    touchWebElement(driver.findElement(by), driver);  }}

There is absolutely no need rename methods, re-package any classes or perform other types of Maven/Gradle stunts here.