如何修复PageFactory,initElements给出的无法使受保护的最终java.lang.Class问题?

h7appiyu  于 2022-12-17  发布在  Java
关注(0)|答案(1)|浏览(162)

我正在进行我的第一个专业项目,从头开始构建一个Appium自动化。为了初始化我的驱动程序,我使用了一个侦听器,它

public class TestListener implements ITestListener{

    @Override
    public void onTestStart(ITestResult result) {
        ITestListener.super.onTestStart(result);
        String platform = result.getMethod().getXmlTest().getLocalParameters().get("platform");

        if(platform.contains("android"))
        {
            try {
                AppFactory.Android_LaunchAPP();
            } catch (MalformedURLException e) {
                e.printStackTrace();
            }
        }else
        if(platform.contains("ios")){
            try {
                AppFactory.IOS_LaunchAPP();
            } catch (MalformedURLException e) {
                e.printStackTrace();
            }
        }

    }

我的工厂类:

public class AppFactory {

    public static DesiredCapabilities capabilities;
    public static AppiumDriver driver;

    public static void Android_LaunchAPP() throws MalformedURLException {
        capabilities  = new DesiredCapabilities();
        capabilities.setCapability("deviceName","Galaxy S10+");
        capabilities.setCapability("udid","xxxxxxx");
        capabilities.setCapability("platformName","Android");
        capabilities.setCapability("platformVersion","12");
        capabilities.setCapability("appPackage","xxxxxxxx");
        capabilities.setCapability("appActivity","xxxxxxx");

        URL url = new URL("http://127.0.0.1:4723/wd/hub");

        driver = new AppiumDriver(url, capabilities);
        driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);

        AppDriver.setDriver(driver);
    }

    public static void IOS_LaunchAPP() throws MalformedURLException{
        DesiredCapabilities capabilities = new DesiredCapabilities();
        capabilities.setCapability("deviceName","Galaxy S10+");
        capabilities.setCapability("udid","R58N91SRTCB");
        capabilities.setCapability("platformName","Android");
        capabilities.setCapability("platformVersion","12");
        capabilities.setCapability("appPackage","vendemas.niubiz.com.pe.qa");
        capabilities.setCapability("appActivity","niubiz.lima.mobile.android.core.MainActivity");

        driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
        AppDriver.setDriver(driver);
    }

    public void closeApp(){
        driver.quit();
    }
}

我的司机是:

public class AppDriver {

    private static final ThreadLocal<WebDriver> driver = new ThreadLocal<>();

    public static WebDriver getDriver(){
        return driver.get();
    }

    static void setDriver(WebDriver Driver){
        driver.set(Driver);
    }
}

以下是定义步骤

public class LoginSteps {
    private final WelcomeScreen welcomeScreen = new WelcomeScreen();

    @Given("Estoy en la pantalla de Inicio")
    public void estoyEnLaPantallaDeInicio() {
    }

    @When("Selecciono Ya estoy registrado")
    public void seleccionoYaEstoyRegistrado() {
        welcomeScreen.tapYaEstoyRegistrado();
    }

我从TestNG.XML文件运行我的代码,我使用 cucumber frogerkin语言问题是,当我尝试initialize de PageFactory.initElements.在页面的构造函数中的第一步,它返回以下内容:

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.

io.cucumber.core.exception.CucumberException: Failed to instantiate class StepsDefinitions.LoginSteps

    at io.cucumber.core.backend.DefaultObjectFactory.cacheNewInstance(DefaultObjectFactory.java:67)
    at io.cucumber.core.backend.DefaultObjectFactory.getInstance(DefaultObjectFactory.java:45)
    at io.cucumber.java.AbstractGlueDefinition.invokeMethod(AbstractGlueDefinition.java:47)
    at io.cucumber.java.JavaStepDefinition.execute(JavaStepDefinition.java:29)
    at io.cucumber.core.runner.CoreStepDefinition.execute(CoreStepDefinition.java:66)
    at io.cucumber.core.runner.PickleStepDefinitionMatch.runStep(PickleStepDefinitionMatch.java:63)
    at io.cucumber.core.runner.ExecutionMode$1.execute(ExecutionMode.java:10)
    at io.cucumber.core.runner.TestStep.executeStep(TestStep.java:85)
    at io.cucumber.core.runner.TestStep.run(TestStep.java:57)
    at io.cucumber.core.runner.PickleStepTestStep.run(PickleStepTestStep.java:51)
    at io.cucumber.core.runner.TestCase.run(TestCase.java:84)
    at io.cucumber.core.runner.Runner.runPickle(Runner.java:75)
    at io.cucumber.testng.TestNGCucumberRunner.lambda$runScenario$1(TestNGCucumberRunner.java:132)
    at io.cucumber.core.runtime.CucumberExecutionContext.lambda$runTestCase$5(CucumberExecutionContext.java:129)
    at io.cucumber.core.runtime.RethrowingThrowableCollector.executeAndThrow(RethrowingThrowableCollector.java:23)
    at io.cucumber.core.runtime.CucumberExecutionContext.runTestCase(CucumberExecutionContext.java:129)
    at io.cucumber.testng.TestNGCucumberRunner.runScenario(TestNGCucumberRunner.java:129)
    at io.cucumber.testng.AbstractTestNGCucumberTests.runScenario(AbstractTestNGCucumberTests.java:35)
    at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
    at java.base/java.lang.reflect.Method.invoke(Method.java:578)
    at org.testng.internal.invokers.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:139)
    at org.testng.internal.invokers.TestInvoker.invokeMethod(TestInvoker.java:677)
    at org.testng.internal.invokers.TestInvoker.invokeTestMethod(TestInvoker.java:221)
    at org.testng.internal.invokers.MethodRunner.runInSequence(MethodRunner.java:50)
    at org.testng.internal.invokers.TestInvoker$MethodInvocationAgent.invoke(TestInvoker.java:962)
    at org.testng.internal.invokers.TestInvoker.invokeTestMethods(TestInvoker.java:194)
    at org.testng.internal.invokers.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:148)
    at org.testng.internal.invokers.TestMethodWorker.run(TestMethodWorker.java:128)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
    at org.testng.TestRunner.privateRun(TestRunner.java:806)
    at org.testng.TestRunner.run(TestRunner.java:601)
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:433)
    at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:427)
    at org.testng.SuiteRunner.privateRun(SuiteRunner.java:387)
    at org.testng.SuiteRunner.run(SuiteRunner.java:330)
    at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
    at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:95)
    at org.testng.TestNG.runSuitesSequentially(TestNG.java:1256)
    at org.testng.TestNG.runSuitesLocally(TestNG.java:1176)
    at org.testng.TestNG.runSuites(TestNG.java:1099)
    at org.testng.TestNG.run(TestNG.java:1067)
    at com.intellij.rt.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:66)
    at com.intellij.rt.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:109)
Caused by: java.lang.reflect.InvocationTargetException
    at java.base/jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(DirectConstructorHandleAccessor.java:79)
    at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:500)
    at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:484)
    at io.cucumber.core.backend.DefaultObjectFactory.cacheNewInstance(DefaultObjectFactory.java:53)
    ... 42 more
Caused by: java.lang.ExceptionInInitializerError
    at io.appium.java_client.pagefactory.utils.ProxyFactory.getEnhancedProxy(ProxyFactory.java:53)
    at io.appium.java_client.pagefactory.utils.ProxyFactory.getEnhancedProxy(ProxyFactory.java:33)
    at io.appium.java_client.pagefactory.AppiumFieldDecorator.proxyForAnElement(AppiumFieldDecorator.java:209)
    at io.appium.java_client.pagefactory.AppiumFieldDecorator.access$000(AppiumFieldDecorator.java:61)
    at io.appium.java_client.pagefactory.AppiumFieldDecorator$1.proxyForLocator(AppiumFieldDecorator.java:100)
    at org.openqa.selenium.support.pagefactory.DefaultFieldDecorator.decorate(DefaultFieldDecorator.java:63)
    at io.appium.java_client.pagefactory.AppiumFieldDecorator.decorate(AppiumFieldDecorator.java:147)
    at org.openqa.selenium.support.PageFactory.proxyFields(PageFactory.java:111)
    at org.openqa.selenium.support.PageFactory.initElements(PageFactory.java:103)
    at Screens.WelcomeScreen.<init>(WelcomeScreen.java:14)
    at StepsDefinitions.LoginSteps.<init>(LoginSteps.java:14)
    at java.base/jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(DirectConstructorHandleAccessor.java:67)
    ... 45 more
Caused by: net.sf.cglib.core.CodeGenerationException: java.lang.reflect.InaccessibleObjectException-->Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) throws java.lang.ClassFormatError accessible: module java.base does not "opens java.lang" to unnamed module @1a407d53
    at net.sf.cglib.core.ReflectUtils.defineClass(ReflectUtils.java:464)
    at net.sf.cglib.core.AbstractClassGenerator.generate(AbstractClassGenerator.java:339)
    at net.sf.cglib.core.AbstractClassGenerator$ClassLoaderData$3.apply(AbstractClassGenerator.java:96)
    at net.sf.cglib.core.AbstractClassGenerator$ClassLoaderData$3.apply(AbstractClassGenerator.java:94)
    at net.sf.cglib.core.internal.LoadingCache$2.call(LoadingCache.java:54)
    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
    at net.sf.cglib.core.internal.LoadingCache.createEntry(LoadingCache.java:61)
    at net.sf.cglib.core.internal.LoadingCache.get(LoadingCache.java:34)
    at net.sf.cglib.core.AbstractClassGenerator$ClassLoaderData.get(AbstractClassGenerator.java:119)
    at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:294)
    at net.sf.cglib.core.KeyFactory$Generator.create(KeyFactory.java:221)
    at net.sf.cglib.core.KeyFactory.create(KeyFactory.java:174)
    at net.sf.cglib.core.KeyFactory.create(KeyFactory.java:153)
    at net.sf.cglib.proxy.Enhancer.<clinit>(Enhancer.java:73)
    ... 57 more
Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) throws java.lang.ClassFormatError accessible: module java.base does not "opens java.lang" to unnamed module @1a407d53
    at java.base/java.lang.reflect.AccessibleObject.throwInaccessibleObjectException(AccessibleObject.java:387)
    at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:363)
    at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:311)
    at java.base/java.lang.reflect.Method.checkCanSetAccessible(Method.java:201)
    at java.base/java.lang.reflect.Method.setAccessible(Method.java:195)
    at net.sf.cglib.core.ReflectUtils$1.run(ReflectUtils.java:61)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:569)
    at net.sf.cglib.core.ReflectUtils.<clinit>(ReflectUtils.java:52)
    at net.sf.cglib.core.KeyFactory$Generator.generateClass(KeyFactory.java:243)
    at net.sf.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25)
    at net.sf.cglib.core.AbstractClassGenerator.generate(AbstractClassGenerator.java:332)
    ... 69 more

以下是尝试初始化元素的页面:

public class WelcomeScreen extends Base {

    public WelcomeScreen(){
        PageFactory.initElements(new AppiumFieldDecorator(AppDriver.getDriver()), this);
    }

    @AndroidFindBy(xpath = "/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/androidx.compose.ui.platform.ComposeView/android.view.View/android.view.View[2]/android.widget.Button")
    @iOSXCUITFindBy()
    private WebElement yaEstoyRegistrado_btn;

    public void tapYaEstoyRegistrado(){
        tapWebElement(yaEstoyRegistrado_btn);
    }

}

我安装了Gradle,尝试在@Before、@BeforeMethod、@BeforeClass上初始化驱动程序,但没有任何效果。我使用的是Java 19,有人知道如何解决这个问题吗?

n3ipq98p

n3ipq98p1#

Page Factory不再适用于Java JDK 16及以上版本的Appium。请参考我提交的此缺陷以了解有关此问题的更多详细信息:https://github.com/appium/java-client/issues/1619
作为一种变通办法,
您可以将Java JDK降级到15或更低(如果使用Eclipse,您可能需要导航到“项目设置”并将默认JRE更改为您的Java版本)

如果无法降级Java,则在pom.xml中添加以下代码段(您可能希望使用最新版本的maven-surefire-plugin)。

<properties>
     <jvm.options>--add-opens java.base/java.lang=ALL-UNNAMED</jvm.options>
    </properties>

  <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>3.0.0-M5</version>
                <configuration>
                    <argLine>${jvm.options}</argLine>
                </configuration>
            </plugin>
        </plugins>
    </build>

对于基于Gradle的项目,您可能需要将Java JDK降级到15或更低版本,然后检查这是否能解决问题。我不确定上述解决方案是否也适用于Gradle。

相关问题