Home > Mobile >  How to fix PageFactory.initElements giving Unable to make protected final java.lang.Class problem?
How to fix PageFactory.initElements giving Unable to make protected final java.lang.Class problem?

Time:12-16

I am working in my first professional project building an Appium automation from scratch. To initialize my Driver I am using a Listener that

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

    }

My Factory class:

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

And My driver is a:

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

here is steps def

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

I Run my code from a TestNG.XML file, and I am using cucumber fro gherkin language The problem is that when I try to initiliaze de PageFactory.initElements. in the constructor of a page for the first step it returns the following:

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

Here is the page that tries to initialize the Elements:

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

}

I have installed Gradle, tried to initialize the driver on @Before, @BeforeMethod, @BeforeClass, and nothing works I am using Java 19, does anyone know how to solve this?

CodePudding user response:

Checho mas gay que las otras preguntas de stackoverflow.

CodePudding user response:

Page Factory is no more working for Appium with Java JDK 16 and above. Refer this defect filed by me for more detail on this issue: https://github.com/appium/java-client/issues/1619

As a workaround,

You can either downgrade Java JDK to 15 or below (if using Eclipse, you may need to navigate to Project Settings and change the default JRE to your Java version)

OR

If downgrading Java is not an option, then add below snippet in the pom.xml (you may want to use latest version of 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>

For Gradle based project, you may want to downgrade your Java JDK to 15 or below and check if that solves the problem. I'm not sure if above workaround would work for Gradle too.

  • Related