aulas duplicados em diferentes Java bibliotecas leva a erros de compilação

AndiCover:

Estou tendo problemas com o cliente java Appium porque parece que eles fizeram coisas estranhas com o seu projeto.

Basicamente, eles estão usando selênio em seu projeto, que deve funcionar muito bem, mas eles copiado um pacote de selênio em parte para seu projeto ( org.openqa.selenium ) e fez algumas pequenas adaptações para as classes dentro. Basicamente, eles adicionaram genéricos para as interfaces. Agora temos aulas duplicados no mesmo pacote em diferentes bibliotecas que de leads curso para os problemas.

Eu criei um projeto simples Gradle para demonstrar isso. Depois da minha build.gradle :

plugins {
    id 'java-library'
}

dependencies {
    api 'io.appium:java-client:6.1.0'
}

repositories {
    jcenter()
}

E minha classe Interactions.java :

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;

public class Interactions {

    public static void touchWebElement(By by, WebDriver driver) {
        touchWebElement(driver.findElement(by), driver);
    }

    public static void touchWebElement(WebElement element, WebDriver driver) {
        // DO SOMETHING
    }
}

Agora, se eu compilar esse projeto eu recebo o seguinte erro:

The method touchWebElement(By, WebDriver) is ambiguous for the type Interactions    Interactions.java   line 8

Eu acho que é ambígua porque a interface WebElement existe duas vezes.

Como posso resolver esse problema?

  • Usando appium-cliente <= 4.0.0 iria funcionar, mas eu preciso de uma versão mais recente.
  • Atualmente, eu acabei de excluir o pacote duplicado do frasco e incluiu este frasco em meu projeto. Eu realmente só apagou com 7zip. Isso limpa que erro de compilação, mas eu provavelmente em breve enfrentar outros problemas porque o frasco appium não está completa e o projeto appium nem sequer compilar sem esse pacote.
  • Os caras selênio provavelmente não vai mudar nada ( https://github.com/SeleniumHQ/selenium/pull/863 ).
  • Os caras Appium provavelmente não sabe como corrigir isso, eu também: https://github.com/appium/java-client/issues/1021

Solução:

Com a ajuda da resposta aceita eu era capaz de corrigir esses problemas. Embora eu precisava para chegar a uma solução ligeiramente diferente. O problema que enfrentamos foi que as classes que chamavam meu Interactions.java precisava daqueles moldes também que conduziria, em 1000 adaptações. Para evitar isso eu mudei meus métodos para tirar Object como parâmetro:

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;

public class Interactions {
    public static void touchWebElement(Object object, WebDriver driver){
        WebElement webElement = castObjectToWebElement(element, driver);
        //DO SOMETHING
    }

    private static WebElement castObjectToWebElement(Object object, WebDriver driver) {
        if (object instanceof WebElement) {
            return (WebElement) object;
        } else if (object instanceof By) {
            return driver.findElement((By) object);
        }
        throw new IllegalArgumentException("Invalid type");
    }
}

Pode não ser a solução ideal, mas funciona e não vai precisar de mudanças em todas as outras classes e todos podem trabalhar com esses métodos de interação como até agora.

kriegaex:

O problema não são classes duplicadas, mas a forma como os genéricos são usados. Aqui é um pouco MCVE replicar a situação do Appium WebDriverclasse:

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

Explicação: Devido à eliminação de tipo doSomething é tipo de retorno genéricos <T extends WebElement>avalia a Object, então ao tentar usar esse resultado para chamar myOverloadedMethod(..)o compilador não saber qual o método para selecionar.

Solução: Você precisa de ajuda, lançando ou explicitamente declarar um tipo para uma variável que contém o parâmetro do método.

PS: Se você modificar a definição de interface a partir interface WebDriverde interface WebDriver<T>, o erro de compilação iria embora. Mas a implementação do Appium não faz isso, talvez porque eles querem ficar como compatível (?) Quanto possível para a classe selênio originais. Você tem que perguntar-lhes.


Update: Como o OP parece ter problemas compreender a minha resposta ou para acreditar que eu não tentar o seu código de exemplo, que é claro que eu utilizado para reproduzir e entender o seu problema:

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

Não há absolutamente nenhum método necessidade renomear, re-embalar quaisquer classes ou realizar outros tipos de acrobacias Maven / Gradle aqui.

Acho que você gosta

Origin http://43.154.161.224:23101/article/api/json?id=175488&siteId=1
Recomendado
Clasificación