question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

IllegalArgumentException when calling PageFactory.initElements(new AppiumFieldDecorator(androidDriver), this)

See original GitHub issue

The problem

When trying to init PageObjects classes with annotations like AndroidFindBy, i am unable to get past the PageFactory.initElements(new AppiumFieldDecorator(androidDriver), this). Test will fail with illegal argument exception and not much details as to which argument is invalid and why.

Environment

appium version: 1.10.1 appium java client: 7.0.0 node ver: v9.10.1 android im: pixel 2 xl api 27 desktop: mac (latest)

Link to Appium logs

Appium log: https://gist.github.com/bill2605/583f868e59f7852f4aebfc42f942c6cd

Code To Reproduce Issue

Note that i am using Spring for my framework. That being said below is the code to initialize an AndroidDriver to be used by the pageObjects.

`@Service @Profile(“android”) public class AndroidDriverLoader {

private final Logger logger = LoggerFactory.getLogger(AndroidDriverLoader.class);

@Resource
protected ConfigProperty configProperty;

public AndroidDriver<AndroidElement> driver;
private AppiumDriverLocalService appiumDriverLocalService;

@PostConstruct
public void androidDriverLoaderInit() {
    loadDriver();
}

/**
 * load the specific android driver based on reference
 */
private void loadDriver() {
    final DesiredCapabilities desiredCapabilities = new DesiredCapabilities();

    if (Objects.equals(configProperty.getMobileType(), "emulator")) {
        desiredCapabilities.setCapability(AndroidMobileCapabilityType.AVD, configProperty.getAndroidAvd());
        desiredCapabilities.setCapability(MobileCapabilityType.APP, configProperty.getAndroidApp());

        appiumDriverLocalService = getDefaultAppiumLocalService();
        appiumDriverLocalService.start();

        driver = new AndroidDriver<>(appiumDriverLocalService, getDefaultAndroidCapabilities().merge(desiredCapabilities));
    } 
}

private DesiredCapabilities getDefaultAndroidCapabilities() {
    final DesiredCapabilities desiredCapabilities = new DesiredCapabilities();
    desiredCapabilities.setCapability(MobileCapabilityType.AUTOMATION_NAME, AutomationName.ANDROID_UIAUTOMATOR2);
    desiredCapabilities.setCapability(MobileCapabilityType.PLATFORM_NAME, Platform.ANDROID);
    desiredCapabilities.setCapability(MobileCapabilityType.DEVICE_NAME, configProperty.getAndroidDeviceName());
    desiredCapabilities.setCapability(AndroidMobileCapabilityType.NO_SIGN, true);
    desiredCapabilities.setCapability(MobileCapabilityType.FULL_RESET, false);
    desiredCapabilities.setCapability(MobileCapabilityType.NO_RESET, true);
    desiredCapabilities
            .setCapability(MobileCapabilityType.NEW_COMMAND_TIMEOUT, Integer.parseInt(configProperty.getCommandTimeOut()));

    return desiredCapabilities;
}

/**
 * return default appium local service
 *
 * @return {@link AppiumDriverLocalService}
 */
private AppiumDriverLocalService getDefaultAppiumLocalService() {
    return new AppiumServiceBuilder()
            .usingDriverExecutable(Paths.get(configProperty.getAppiumDriverExecutable()).toFile())
            .withAppiumJS(Paths.get(configProperty.getAppiumJs()).toFile())
            .withIPAddress(configProperty.getServiceIPAddress())
            .usingPort(Integer.parseInt(configProperty.getAppiumPort()))
            .withArgument(GeneralServerFlag.LOCAL_TIMEZONE)
            .build();
}

public AndroidDriver<AndroidElement> getDriver() {
    return driver;
}`

Each PageObject extends AndroidAbstractView which holds the following information: `@Service @Profile(“android”) public abstract class AndroidAbstractView implements RemoteElementUtils<AndroidElement> {

private final Logger logger = LoggerFactory.getLogger(AndroidAbstractView.class);

@Resource
protected AndroidDriverLoader androidDriverLoader;
@Resource
protected ConfigProperty configProperty;

protected static AppiumDriver androidDriver;

private String iconLoadingId = "item_loading_view";
private String loadingViewRefreshXpath = "//android.view.ViewGroup[contains(@resource-id, 'id/swipe_refresh_layout')]/android.widget.ImageView";

@PostConstruct
protected abstract void init();

Note that RemoteElementUtils is just an interface for all findElementby, waitForVisibible to be implemented for Web, Android and IOS (nothing fancy there)

PageObject is as follow: `@Service @Profile(“android”) public class LoginView extends AndroidAbstractView {

@AndroidFindBy(xpath = "//*[contains(@resource-id, 'login_username_auto_complete_text_view')]")
protected AndroidElement inputUserName;
@AndroidFindBy(xpath = "//*[contains(@resource-id, 'login_next_button')]")
protected AndroidElement buttonContinue;
@AndroidFindBy(xpath = "//*[contains(@resource-id, 'login_password_edit_text')]")
protected AndroidElement inputPassword;
@AndroidFindBy(xpath = "//*[contains(@resource-id, 'login_password_log_in_button')]")
protected AndroidElement buttonLogin;
@AndroidFindBy(id = "login_username_dev_stuff_button")
protected AndroidElement buttonDevStuff;
@AndroidFindBy(id = "def_stuff_api_base_url_edit_text")
protected AndroidElement inputApiEndPointUrl;
@AndroidFindBy(id = "def_stuff_api_base_url_button")
protected AndroidElement buttonApply;

@PostConstruct
public void init()
{
    this.androidDriver = androidDriverLoader.getDriver();
    PageFactory.initElements(new AppiumFieldDecorator(androidDriver), this);
}

public void login(final String userName, final String password) {...}`

When running a test for android, using debugger i see that the driver is created and ready to be used. but whenever it reaches PageFactory.initElements(new AppiumFieldDecorator(androidDriver), this);

the following error is returned: Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'loginView': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException Exception in thread "main" java.lang.IllegalStateException: Failed to load ApplicationContext at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:124) at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:83) at cucumber.runtime.java.spring.CucumberTestContextManager.getContext(SpringFactory.java:247) at cucumber.runtime.java.spring.CucumberTestContextManager.<init>(SpringFactory.java:239) at cucumber.runtime.java.spring.SpringFactory.start(SpringFactory.java:132) at cucumber.runtime.java.JavaBackend.buildWorld(JavaBackend.java:114) at cucumber.runner.Runner.buildBackendWorlds(Runner.java:120) at cucumber.runner.Runner.runPickle(Runner.java:38) at cucumber.runtime.Runtime$1.run(Runtime.java:84) at cucumber.runtime.Runtime$SameThreadExecutorService.execute(Runtime.java:220) at cucumber.runtime.Runtime.run(Runtime.java:81) at cucumber.api.cli.Main.run(Main.java:26) at cucumber.api.cli.Main.main(Main.java:8) Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'loginView': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:139) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:419) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1736) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:576) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:498) at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:848) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:865) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:548) at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:128) at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:60) at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.delegateLoading(AbstractDelegatingSmartContextLoader.java:108) at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.loadContext(AbstractDelegatingSmartContextLoader.java:251) at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:98) at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:116) ... 12 more Caused by: java.lang.IllegalArgumentException at net.sf.cglib.asm.ClassReader.<init>(Unknown Source) at net.sf.cglib.asm.ClassReader.<init>(Unknown Source) at net.sf.cglib.asm.ClassReader.<init>(Unknown Source) at net.sf.cglib.proxy.BridgeMethodResolver.resolveAll(BridgeMethodResolver.java:61) at net.sf.cglib.proxy.Enhancer.emitMethods(Enhancer.java:911) at net.sf.cglib.proxy.Enhancer.generateClass(Enhancer.java:498) at net.sf.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25) at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:216) at net.sf.cglib.proxy.Enhancer.createHelper(Enhancer.java:377) at net.sf.cglib.proxy.Enhancer.create(Enhancer.java:304) at io.appium.java_client.pagefactory.utils.ProxyFactory.getEnhancedProxy(ProxyFactory.java:55) at io.appium.java_client.pagefactory.utils.ProxyFactory.getEnhancedProxy(ProxyFactory.java:33) at io.appium.java_client.pagefactory.AppiumFieldDecorator.proxyForAnElement(AppiumFieldDecorator.java:217) at io.appium.java_client.pagefactory.AppiumFieldDecorator.access$0(AppiumFieldDecorator.java:215) at io.appium.java_client.pagefactory.AppiumFieldDecorator$1.proxyForLocator(AppiumFieldDecorator.java:107) at org.openqa.selenium.support.pagefactory.DefaultFieldDecorator.decorate(DefaultFieldDecorator.java:62) at io.appium.java_client.pagefactory.AppiumFieldDecorator.decorate(AppiumFieldDecorator.java:155) at org.openqa.selenium.support.PageFactory.proxyFields(PageFactory.java:113) at org.openqa.selenium.support.PageFactory.initElements(PageFactory.java:105) at com.workjam.platform.frontend.android.view.LoginView.init(LoginView.java:35) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:363) at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:307) at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:136) ... 29 more

When attempting to debug code i made it all the way to method from io.appium.java_client.pagefactory.utils.ProxyFactory;

public static <T> T getEnhancedProxy(Class<T> requiredClazz, Class<?>[] params, Object[] values, MethodInterceptor interceptor) { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(requiredClazz); enhancer.setCallback(interceptor); return (T) enhancer.create(params, values); }

and crash occurs at return (T) enhancer.create(params, values);

Issue Analytics

  • State:open
  • Created 5 years ago
  • Comments:12 (1 by maintainers)

github_iconTop GitHub Comments

18reactions
canaangiffordcommented, Jun 13, 2019

I encountered a similar issue as well on version 6.1.0 of the java-client. I spent some time looking into the root cause, and it seems as though this particular use of the AppiumFieldDecorator with @AndroidFindBy or @iOSFindBy may have been broken as of this dependency change: #832

I was unable to get the cglib Enhancer class to instantiate on line 52 of the ProxyFactory class. Enhancer enhancer = new Enhancer();

java.lang.NoClassDefFoundError: Could not initialize class net.sf.cglib.proxy.Enhancer

A work-around for now is to exclude the cglib version from the appium java-client dependency in favor of specifying an older version.

    <dependency>
        <groupId>io.appium</groupId>
        <artifactId>java-client</artifactId>
        <version>6.1.0</version>
        <exclusions>
            <exclusion>
                <groupId>cglib</groupId>
                <artifactId>cglib</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

    <!-- This is required for page factory use with Appium -->
    <dependency>
        <groupId>cglib</groupId>
        <artifactId>cglib</artifactId>
        <version>3.2.5</version>
    </dependency>

I’m not sure if this will resolve the exact issue that @bill2605 is seeing, but it fixed my issue. Is there a specific reason why the java-client relies on cglib 3.2.5+?

0reactions
prasanta-biswascommented, May 24, 2021

Still facing this issue in appium java client and 7.5.1. Any plan to fix this?

Although excluding cglib from java client and manually adding cglib 3.2.5 solved the issue.

Read more comments on GitHub >

github_iconTop Results From Across the Web

java - Illegal Argument Exception in Appium framework
I am using Appium server 1.8.1, selenium 3.13.0 and java client 6.1.0. I use the page object model like following and it works...
Read more >
Getting issue in WebDriverListener implementation with ...
PageFactory.initElements(new AppiumFieldDecorator(baseMobileDriver), this);. now I am using this. PageFactory.initElements(new AppiumElementLocatorFactory( ...
Read more >
io.appium.java_client.pagefactory.AppiumFieldDecorator.<init ...
cachedInstances.put(type, widget); PageFactory.initElements(new AppiumFieldDecorator(widget, duration), widget);
Read more >
IllegalArgumentException if I skip the Step Library layer
PageFactory.initElements(new AppiumFieldDecorator(myDriver, this.getImplicitWaitTimeout().in(TimeUnit.SECONDS), TimeUnit.SECONDS), this); }
Read more >
GETTING STARTED WITH APPIUM
driver we'll be using is appium-xcuitest-driver, and the Android driver ... PageFactory.initElements(new AppiumFieldDecorator(driver), this);.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found