java-client icon indicating copy to clipboard operation
java-client copied to clipboard

Not able to run mobile app tests using mvn clean test command and seen errors java. lang. NoClassDefFoundError: org/openqa/selenium/remote/RemoteWebElement & java. lang. NoClassDefFoundError: io/appium/java_client/proxy/HasMethodCallListeners.

Open pothurajtharun opened this issue 1 year ago • 13 comments

Description

When i try to run the mobile app test cases using the below configurations then I'm facing multiple issues as mentioned in this ticket.

  • appium-java-client 9.0.0 vs Selenium 4.14.1 : java. lang. NoClassDefFoundError: org/openqa/selenium/remote/RemoteWebElement
  • appium-java-client 9.1.0 vs Selenium 4.17.0 : java. lang. NoClassDefFoundError: io/appium/java_client/proxy/HasMethodCallListeners

Environment

  • Java client build version or git revision if you use some snapshot: 9.0.0/9.1.0
  • Appium server version or git revision if you use some snapshot: 2.4.0
  • Desktop OS/version used to run Appium if necessary: macOS 13.6.3 (22G436)
  • Node.js version (unless using Appium.app|exe) or Appium CLI or Appium.app|exe: v18.16.0
  • Mobile platform/version under test: iPhone 8 Plus(16.7.3)
  • Real device or emulator/simulator: Real Device

Details

I ran mobile app test cases on the above configurations using maven commands mvn clean test but saw multiple errors as mentioned in the above description and not able to run the tests successfully.

Code To Reproduce Issue [ Good To Have ]

Sorry at the moment I can't share the code as it is company licensed.

Exception Stacktraces

9.0.0 Error Stack Trace:

java. lang. NoClassDefFoundError: org/openqa/selenium/remote/RemoteWebElement 
at java.base/java. lang. ClassLoader. defineClass1 (Native Method) at java.base/java. lang. ClassLoader. defineClass (ClassLoader. java:1027)
at net. bytebuddy. dynamic. loading. ByteArrayClassLoader .access$300 (ByteArrayClassLoader. java:57) 
at net. bytebuddy. dynamic. loading. ByteArrayClassLoader$ClassDefinitionAction.run(ByteArrayClassLoader.java:687) 
at net. bytebuddy. dynamic. loading. ByteArrayClassLoader$ClassDefinitionAction.run(ByteArrayClassLoader.java:639) 
at java.base/java.security.AccessController. doPrivileged (AccessController. java:400) at net.bytebuddy.dynamic. loading. ByteArrayClassLoader .doPrivileged (ByteArrayClassLoader. java) 
at net.bytebuddy.dynamic.loading.ByteArrayClassLoader.findClass(ByteArrayClassLoader.java:406) 
at java.base/java.lang. ClassLoader. loadClass (ClassLoader. java: 593) 
at java.base/java. lang. ClassLoader. loadClass (ClassLoader. java:526) 
at java.base/java. lang. Class. forName (Native Method) at java.base/java. lang. Class. forName (Class. java: 534) 
at java.base/java. lang. Class.forName (Class. java: 513)
at net.bytebuddy.dynamic.loading. ByteArrayClassLoader. load (ByteArrayClassLoader. java:361) 
at net.bytebuddy .dynamic. loading. ClassLoadingStrategy$Default$WrappingDispatcher.load(ClassLoadingStrategy.java:367) 
at net.bytebuddy.dynamic. loading. ClassLoadingStrategy$Default. load (ClassLoadingStrategy. java:148) 
at net.bytebuddy .dynamic. TypeResolutionStrategy$Passive.initialize (TypeResolutionStrategy. java: 101) 
at net.bytebuddy.dynamic.DynamicType$Default$Unloaded. load (DynamicType. java:6317) 
at io.appium.java_client.proxy. Helpers. createProxy (Helpers.java:121)
at io.appium.java_client.pagefactory.utils.ProxyFactory.getEnhancedProxy(ProxyFactory.java:96)
at io.appium.java_client.pagefactory.utils.ProxyFactory.getEnhancedProxy(ProxyFactory.java:71)
at io.appium.java_client.pagefactory.AppiumFieldDecorator.proxyForAnElement(AppiumFieldDecorator.java:248)

9.1.0 Error Stack Trace:

java. lang. NoClassDefFoundError: io/appium/java_client/proxy/HasMethodCallListeners at java.base/java. lang. ClassLoader. defineClass1 (Native Method) 
at java.base/java.lang. ClassLoader .defineClass (ClassLoader. java: 1027)
at net.bytebuddy.dynamic.loading. ByteArrayClassLoader.access$300 (ByteArrayClassLoader.java:57) 
at net. bytebuddy. dynamic. loading. ByteArrayClassLoader$ClassDefinitionAction.run(ByteArrayClassLoader.java:687) 
at net.bytebuddy.dynamic. loading.ByteArrayClassLoader$ClassDefinitionAction.run(ByteArrayClassLoader.java:639) 
at java.base/java.security.AccessController .doPrivileged (AccessController. java: 400) 
at net.bytebuddy. dynamic. loading. ByteArrayClassLoader. doPrivileged (ByteArrayClassLoader. java) 
at net.bytebuddy.dynamic.loading. ByteArrayClassLoader. findClass (ByteArrayClassLoader. java: 406) 
at java.base/java. lang. ClassLoader. loadClass (ClassLoader. java: 593) 
at java.base/java. lang. ClassLoader. loadClass (ClassLoader. java:526) 
at java.base/java.lang.Class.forName0(Native Method) 
at java. base/java. lang. Class. forName (Class. java: 534) 
at java.base/java. lang. Class.forName (Class. java: 513)
at net.bytebuddy.dynamic.loading.ByteArrayClassLoader.load(ByteArrayClassLoader.java:361)
at net .bytebuddy. dynamic. loading. ClassLoadingStrategy$Default$WrappingDispatcher.load(ClassLoadingStrategy.java:367) 
at net.bytebuddy. dynamic. loading. ClassLoadingStrategy$Default. load(ClassLoadingStrategy. java: 148) 
at net.bytebuddy.dynamic.TypeResolutionStrategy$Passive.initialize(TypeResolutionStrategy.java:101) 
at net .bytebuddy. dynamic. DynamicType$Default$Unloaded. load (DynamicType.java: 6325) 
at io.appium.java_client.proxy. Helpers. createProxy (Helpers. java: 127)
at io.appium.java_client.pagefactory.utils.ProxyFactory.getEnhancedProxy(ProxyFactory.java:95)
at io.appium.java_client.pagefactory.utils.ProxyFactory.getEnhancedProxy(ProxyFactory.java:70)

Link To Appium Logs

9.0.0 Error Logs & Screenshots:

Error_9 0 0

appium-java-client-9.0.0.log

9.1.0 Error Logs & Screenshots:

Error_9 1 0

appium-java-client-9.1.0.log

Please take a look once and let me know if I'm missing something here. All the mentioned dependencies are available in pom.xml and class path.

Thanks in advance!

pothurajtharun avatar Feb 15 '24 08:02 pothurajtharun

bytebuddy uses the system class loader to load classes. In order for classes to be visible to the system loader they must be enumerated in the classpath environment variable, -classpath, or -cp command line option.

mykola-mokhnach avatar Feb 15 '24 11:02 mykola-mokhnach

This appears to be similar to https://github.com/appium/java-client/issues/2058. I have faced the same issue ever since 8.5.1 was released. But starting with 9.1.0, the NoClassDefFoundError error has switched from RemoteWebElement to HasMethodCallListeners. I obey the compatibility matrix with Maven dependencies defined as suggested here.

@mykola-mokhnach, using your hint about enumerating specific classes in the -classpath command-line java option, I was able to eliminate the NoClassDefFoundError errors. I defined a shell environment variable defining paths to the missing JAR files:

export APPIUM_CLASSPATH=/Users/patrickwebster/.m2/repository/io/appium/java-client/9.1.0/java-client-9.1.0.jar:/Users/patrickwebster/.m2/repository/org/seleniumhq/selenium/selenium-api/4.17.0/selenium-api-4.17.0.jar:/Users/patrickwebster/.m2/repository/org/seleniumhq/selenium/selenium-remote-driver/4.17.0/selenium-remote-driver-4.17.0.jar:/Users/patrickwebster/.m2/repository/org/seleniumhq/selenium/selenium-support/4.17.0/selenium-support-4.17.0.jar

I extracted the IntelliJ IDEA Maven run command to the terminal, removed all IDEA-specific options and appended ":$APPIUM_CLASSPATH" to the value of my -classpath JVM option.

The result is no more NoClassDefFoundError errors, but this new error:

java.lang.ClassCastException: class org.openqa.selenium.remote.RemoteWebElement$ByteBuddy$byQ18vpl
	at java.base/java.lang.Class.asSubclass(Class.java:3640)
	at io.appium.java_client.proxy.Helpers.createProxy(Helpers.java:129)
	at io.appium.java_client.pagefactory.utils.ProxyFactory.getEnhancedProxy(ProxyFactory.java:95)
	at io.appium.java_client.pagefactory.utils.ProxyFactory.getEnhancedProxy(ProxyFactory.java:70)
	at io.appium.java_client.pagefactory.AppiumFieldDecorator.proxyForAnElement(AppiumFieldDecorator.java:258)
	at io.appium.java_client.pagefactory.AppiumFieldDecorator$1.proxyForLocator(AppiumFieldDecorator.java:157)
	at org.openqa.selenium.support.pagefactory.DefaultFieldDecorator.decorate(DefaultFieldDecorator.java:61)
	at io.appium.java_client.pagefactory.AppiumFieldDecorator.decorate(AppiumFieldDecorator.java:196)
	at org.openqa.selenium.support.PageFactory.proxyFields(PageFactory.java:109)
	at org.openqa.selenium.support.PageFactory.initElements(PageFactory.java:101)

These problems started when Byte Buddy was introduced in 8.5.1. I'm not sure how to configure the above hack into my project code. I am curious to know if anyone knows a setting in the POM.xml file that can append values to the JVM -classpath option. I experimented with various options like setting useSystemClassLoader to true or false, adding additionalClasspathElements, etc., but none of these achieved the results from the terminal command-line hack. I tried the latest Byte Buddy 1.14.12, but that did not help.

Environment

  • Java client version: 8.5.1, 8.6.0, 9.0.0, 9.1.0
  • Appium server version: 2.5.1
  • Appium drivers: [email protected], [email protected]
  • Desktop OS: macOS 13.6.3
  • Node.js version: v21.2.0
  • Mobile platforms under test: iOS 15, 16, 17; Android 12, 13, 14
  • Real iOS and Android devices

pwebster-cpi avatar Feb 18 '24 07:02 pwebster-cpi

java.lang.ClassCastException: class org.openqa.selenium.remote.RemoteWebElement$ByteBuddy$byQ18vpl

This means the org.openqa.selenium.remote.RemoteWebElement class that was found in the classpath (and instrumented) is different from the one that is currently used. Probably because of Selenium lib versions conflict. Check your dependency tree to verify a single selenium lib version is in use.

mykola-mokhnach avatar Feb 18 '24 08:02 mykola-mokhnach

I removed my entire local Maven cache and the only version on disk after reloading dependencies is 4.17.0 when using java-client 9.1.0, or Selenium version 4.13.0 for java-client 8.5.1. If I make a single character change to the project POM.xml file by changing "8.5.1" to "8.5.0", everything works fine. The dependency list shows only one version of Selenium for any configuration. The effective POM.xml file also shows only one version of the Selenium library.

org.seleniumhq.selenium:selenium-api:4.13.0
org.seleniumhq.selenium:selenium-http:4.13.0
org.seleniumhq.selenium:selenium-json:4.13.0
org.seleniumhq.selenium:selenium-manager:4.13.0
org.seleniumhq.selenium:selenium-os:4.13.0
org.seleniumhq.selenium:selenium-remote-driver:4.13.0
org.seleniumhq.selenium:selenium-support:4.13.0

pwebster-cpi avatar Feb 18 '24 09:02 pwebster-cpi

I am also getting exactly same issue when executing via mvn command:

If running on old versions like Selenium version 4.13.0 for java-client 8.5.1 then: java.lang.NoClassDefFoundError: org/openqa/selenium/remote/RemoteWebElement And If running on latest versions like Selenium version 4.17.0 for java-client 9.1.0 then: java.lang.NoClassDefFoundError: io/appium/java_client/proxy/HasMethodCallListeners

Please help with this!

msr5464 avatar Feb 28 '24 12:02 msr5464

bytebuddy uses the system class loader to load classes. In order for classes to be visible to the system loader they must be enumerated in the classpath environment variable, -classpath, or -cp command line option.

@mykola-mokhnach I am facing the same issue after updating to java-client version: 9.1.0. getting java.lang.NoClassDefFoundError: io/appium/java_client/proxy/HasMethodCallListeners

My question: how and why should I add this to the classpath? it is not an external jar file, it is already included in the project.. Thanks ahead!

Idoserovitz avatar Feb 29 '24 10:02 Idoserovitz

@mykola-mokhnach, is there any way we can get an option to use the old cglib code and bypass the new bytebuddy implementation? I'd like to move off of 8.5.0 to newer builds.

Thanks

pwebster-cpi avatar Feb 29 '24 21:02 pwebster-cpi

@mykola-mokhnach, is there any way we can get an option to use the old cglib code and bypass the new bytebuddy implementation? I'd like to move off of 8.5.0 to newer builds.

Thanks

cglib integration has been dropped for a reason: the lib was poorly maintained and had a critical compatibility issue with newer java versions which had never been fixed.

I see several possible options there for you:

  • Create a fork of cglib, make it work with newer java versions/return it back to maintainable state. Check https://github.com/cglib/cglib for more details
  • Create a local fork of java client. Switch it to (existing) cglib and avoid ever upgrading JDK
  • Create a PR to this repository and fix possible issues. We are happy to accept any help

mykola-mokhnach avatar Feb 29 '24 21:02 mykola-mokhnach

I am also facing this same issue upon running my tests through mvn command on Selenium version 4.17.0 and Appium java client 9.1.0 with Appium server 2.x.x - java.lang.NoClassDefFoundError: io/appium/java_client/proxy/HasMethodCallListeners

I tried with different versions of Selenium and Appium Java client, but issues still happens.

And this is happening only when i am trying to run my tests via Jenkins. However I am able to run my mobile tests successfully in my local.

Please help with this! Appreciate if someone figure out any solution or workaround? Thanks!

vinothpandian18 avatar Apr 24 '24 08:04 vinothpandian18

Hi All, I also encountered the problem.

  • java 17
  • Appium java client 9.2.2

Caused by: java.lang.NoClassDefFoundError: io/appium/java_client/proxy/HasMethodCallListeners at java.base/java.lang.ClassLoader.defineClass1(Native Method) at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1012) at net.bytebuddy.dynamic.loading.ByteArrayClassLoader.access$300(ByteArrayClassLoader.java:57) at net.bytebuddy.dynamic.loading.ByteArrayClassLoader$ClassDefinitionAction.run(ByteArrayClassLoader.java:687) at net.bytebuddy.dynamic.loading.ByteArrayClassLoader$ClassDefinitionAction.run(ByteArrayClassLoader.java:639) at java.base/java.security.AccessController.doPrivileged(AccessController.java:399) at net.bytebuddy.dynamic.loading.ByteArrayClassLoader.doPrivileged(ByteArrayClassLoader.java) at net.bytebuddy.dynamic.loading.ByteArrayClassLoader.findClass(ByteArrayClassLoader.java:406) at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:587) at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520) at java.base/java.lang.Class.forName0(Native Method) at java.base/java.lang.Class.forName(Class.java:467) at net.bytebuddy.dynamic.loading.ByteArrayClassLoader.load(ByteArrayClassLoader.java:361) at net.bytebuddy.dynamic.loading.ClassLoadingStrategy$Default$WrappingDispatcher.load(ClassLoadingStrategy.java:367) at net.bytebuddy.dynamic.loading.ClassLoadingStrategy$Default.load(ClassLoadingStrategy.java:148) at net.bytebuddy.dynamic.TypeResolutionStrategy$Passive.initialize(TypeResolutionStrategy.java:101) at net.bytebuddy.dynamic.DynamicType$Default$Unloaded.load(DynamicType.java:6325) at io.appium.java_client.proxy.Helpers.lambda$createProxy$0(Helpers.java:139) at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1708) at io.appium.java_client.proxy.Helpers.createProxy(Helpers.java:118) at io.appium.java_client.pagefactory.utils.ProxyFactory.getEnhancedProxy(ProxyFactory.java:95) at io.appium.java_client.pagefactory.utils.ProxyFactory.getEnhancedProxy(ProxyFactory.java:70) at io.appium.java_client.pagefactory.AppiumFieldDecorator.proxyForAnElement(AppiumFieldDecorator.java:258) at io.appium.java_client.pagefactory.AppiumFieldDecorator$1.proxyForLocator(AppiumFieldDecorator.java:157) at org.openqa.selenium.support.pagefactory.DefaultFieldDecorator.decorate(DefaultFieldDecorator.java:61) at io.appium.java_client.pagefactory.AppiumFieldDecorator.decorate(AppiumFieldDecorator.java:196) at org.openqa.selenium.support.PageFactory.proxyFields(PageFactory.java:109) at org.openqa.selenium.support.PageFactory.initElements(PageFactory.java:101) at com.vodafone.automation.mobil.mva.pageobjects.login.LoginPage.(LoginPage.java:66) ... 61 more

The problem occurs when AppiumFieldDecorator is used.

Any solution or WA for this issue is appreciated. Thx!

update: The line that throws the exception is: return (new ByteBuddy()).subclass(cls).method(extraMethodMatcher == null ? matcher : matcher.and(extraMethodMatcher)).intercept(MethodDelegation.to(Interceptor.class)).defineField("methodCallListeners", MethodCallListener[].class, new ModifierContributor.ForField[]{Visibility.PRIVATE}).implement(new Type[]{HasMethodCallListeners.class}).intercept(FieldAccessor.ofBeanProperty()).make().load(ClassLoader.getSystemClassLoader(), Default.WRAPPER).getLoaded().asSubclass(cls); method:createProxy Class:io.appium.java_client.proxy.Helpers

AndrasFekete80 avatar Apr 29 '24 07:04 AndrasFekete80

The line that throws the exception is: return (new ByteBuddy()).subclass(cls).method(extraMethodMatcher == null ? matcher : matcher.and(extraMethodMatcher)).intercept(MethodDelegation.to(Interceptor.class)).defineField("methodCallListeners", MethodCallListener[].class, new ModifierContributor.ForField[]{Visibility.PRIVATE}).implement(new Type[]{HasMethodCallListeners.class}).intercept(FieldAccessor.ofBeanProperty()).make().load(ClassLoader.getSystemClassLoader(), Default.WRAPPER).getLoaded().asSubclass(cls); method:createProxy Class:io.appium.java_client.proxy.Helpers

It seems the problem is with the class loaders. If you replace the ClassLoader.getSystemClassLoader() with Helpers.class.getClassLoader() then it is working. Could you please add this modification to the next release?

AndrasFekete80 avatar May 08 '24 07:05 AndrasFekete80

@AndrasFekete80 Thanks for investigating this. Could you please create a PR?

mykola-mokhnach avatar May 08 '24 07:05 mykola-mokhnach

Thanks @AndrasFekete80 for fixing this issue. @mykola-mokhnach Any ETA, when this fix will be available in the next release as this is blocking to run my tests via Jenkins

vinothpandian18 avatar May 23 '24 12:05 vinothpandian18

Hi Guys, Not sure that everyone knows it yet. Latest versions (as of now) works great. No issues for me anymore. appium/9.2.3 selenium/4.21.0 (I use java 11 but not sure it plays a key role here, didn't change jdk since I got issue till now) Cheers, Michael

peacebytes avatar Jul 24 '24 19:07 peacebytes