执行mvn clean test时遇ChromeOptions.setExperimentalOption方法缺失错误
问题:ChromeOptions.setExperimentalOption方法找不到错误
问题背景
运行项目时先遇到NoClassDefError,为解决该问题在pom.xml中显式添加httpclient5依赖后,开始出现java.lang.NoSuchMethodError: org.openqa.selenium.chrome.ChromeOptions.setExperimentalOption错误。
环境配置
项目pom.xml配置
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <artifactId>corporate-action-tests-ui</artifactId> <version>0.0.1-SNAPSHOT</version> <parent> <artifactId>corporate-action-parent</artifactId> <groupId>com.mst.indexes</groupId> <version>0.5.1-SNAPSHOT</version> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>11</maven.compiler.source> <maven.compiler.target>11</maven.compiler.target> <suitefile>SmokeSuite_stg.xml</suitefile> <env>stg</env> <browser>localChrome</browser> <suite>Smoke</suite> <test_region>us-west-2</test_region> <updateBugInJira>false</updateBugInJira> <updateTestRail>true</updateTestRail> <updateReportPortal>false</updateReportPortal> <quitBrowserAfterExecution>true</quitBrowserAfterExecution> </properties> <dependencies> <dependency> <groupId>org.apache.httpcomponents.client5</groupId> <artifactId>httpclient5</artifactId> <version>5.2.1</version> </dependency> <dependency> <groupId>com.mst.indexes</groupId> <artifactId>ui-automation-base</artifactId> <version>1.0.0-SNAPSHOT</version> </dependency> <dependency> <groupId>tech.grasshopper</groupId> <artifactId>extentreports-cucumber6-adapter</artifactId> <version>2.8.2</version> <scope>test</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.20</version> <scope>provided</scope> </dependency> <dependency> <groupId>com.mst.indexes</groupId> <artifactId>corporate-action-dto</artifactId> <version>0.5.1-SNAPSHOT</version> <scope>compile</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <version>2.4</version> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.22.1</version> <configuration> <suiteXmlFiles> <suiteXmlFile>src/test/resources/cisuite/${suitefile}</suiteXmlFile> </suiteXmlFiles> <systemPropertyVariables> <env>${env}</env> <browser>${browser}</browser> <suitefile>${suitefile}</suitefile> <suite>${suite}</suite> <test_region>${test_region}</test_region> <updateBugInJira>${updateBugInJira}</updateBugInJira> <updateTestRail>${updateTestRail}</updateTestRail> <rp.enable>${updateReportPortal}</rp.enable> <quitBrowserAfterExecution>${quitBrowserAfterExecution}</quitBrowserAfterExecution> <webdriver.chrome.driver.cachePath>C:/Users/ppathar/.cache/selenium/chromedriver/win64/126.0.6478.126 </webdriver.chrome.driver.cachePath> </systemPropertyVariables> </configuration> </plugin> </plugins> </build> </project>
公共框架ui-automation-base依赖
<dependency> <groupId>io.github.bonigarcia</groupId> <artifactId>webdrivermanager</artifactId> <version>5.6.0</version> <exclusions> <exclusion> <artifactId>slf4j-api</artifactId> <groupId>org.slf4j</groupId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium-java</artifactId> <version>3.141.59</version> </dependency>
已尝试的无效解决方法
- 硬编码
webdriver.chrome.driver.cachePath,让WebDriver使用缓存中的ChromeDriver - 调用
setBrowserVersion("")方法指定浏览器版本 - 从各依赖中排除httpclient5
- 更新Selenium和WebDriverManager版本
错误堆栈信息
2024-07-10 07:50:22,622 level="INFO" class="i.g.bonigarcia.wdm.WebDriverManager" env="stg" description="Using chromedriver 126.0.6478.126 (resolved driver for Chrome 126)" 2024-07-10 07:50:22,667 level="INFO" class="i.g.bonigarcia.wdm.WebDriverManager" env="stg" description="Exporting webdriver.chrome.driver as C:\Users\ppathar.cache\selenium\chromedriver\win64\126.0.6478.126\chromedriver.exe" java.lang.NoSuchMethodError: org.openqa.selenium.chrome.ChromeOptions.setExperimentalOption(Ljava/lang/String;Ljava/lang/Object;)Lorg/openqa/selenium/chrome/ChromeOptions; at com.morningstar.indexes.ui.test.Base.initializeBrowserSetup(Base.java:87) at com.morningstar.indexes.ui.test.Base.setUp(Base.java:173) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:132) at org.testng.internal.MethodInvocationHelper.invokeMethodConsideringTimeout(MethodInvocationHelper.java:61) at org.testng.internal.ConfigInvoker.invokeConfigurationMethod(ConfigInvoker.java:366) at org.testng.internal.ConfigInvoker.invokeConfigurations(ConfigInvoker.java:320) at org.testng.internal.TestInvoker.runConfigMethods(TestInvoker.java:701) at org.testng.internal.TestInvoker.invokeMethod(TestInvoker.java:527) at org.testng.internal.TestInvoker.invokeTestMethod(TestInvoker.java:174) at org.testng.internal.MethodRunner.runInSequence(MethodRunner.java:46) at org.testng.internal.TestInvoker$MethodInvocationAgent.invoke(TestInvoker.java:822) at org.testng.internal.TestInvoker.invokeTestMethods(TestInvoker.java:147) at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:146) at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:128) at java.base/java.util.ArrayList.forEach(ArrayList.java:1541) at org.testng.TestRunner.privateRun(TestRunner.java:764) at org.testng.TestRunner.run(TestRunner.java:585) at org.testng.SuiteRunner.runTest(SuiteRunner.java:384) at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:378) at org.testng.SuiteRunner.privateRun(SuiteRunner.java:337) at org.testng.SuiteRunner.run(SuiteRunner.java:286) at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:53) at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:96) at org.testng.TestNG.runSuitesSequentially(TestNG.java:1218) at org.testng.TestNG.runSuitesLocally(TestNG.java:1140) at org.testng.TestNG.runSuites(TestNG.java:1069) at org.testng.TestNG.run(TestNG.java:1037) at com.intellij.rt.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:65) at com.intellij.rt.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:105)
WebDriver初始化代码片段
case "localChrome": WebDriverManager.chromedriver().setup(); ChromeOptions cp = new ChromeOptions(); Map<String, Object> prefs = new HashMap<String, Object>(); prefs.put("download.default_directory", downloadsPath); cp.setExperimentalOption("prefs", prefs); if (headlessModeOn.equalsIgnoreCase("true")) { cp.addArguments("--headless"); } driver.set(new ChromeDriver(cp)); break;
解决方案
核心原因分析
NoSuchMethodError根源是依赖版本冲突:
- Selenium 3.x的
ChromeOptions.setExperimentalOption()方法返回值为void,而Selenium 4.x中该方法被修改为返回ChromeOptions(流式API设计)。 - 手动添加的httpclient5依赖间接引入了高版本Selenium,导致编译时和运行时加载的
ChromeOptions类版本不一致;同时Selenium 3.x原生依赖httpclient 4.x,强行引入httpclient5会破坏原有依赖链。
具体解决步骤
方案1:替换httpclient5为兼容Selenium 3的httpclient 4.x
最初的NoClassDefError是缺少httpclient 4.x类,而非需要httpclient5。修改pom.xml:
<!-- 移除httpclient5 --> <!-- <dependency> <groupId>org.apache.httpcomponents.client5</groupId> <artifactId>httpclient5</artifactId> <version>5.2.1</version> </dependency> --> <!-- 添加兼容Selenium 3的httpclient 4.x --> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.14</version> </dependency>
方案2:强制统一Selenium版本,排除冲突依赖
执行mvn dependency:tree查看依赖树,找到引入高版本Selenium的组件,在ui-automation-base依赖中排除冲突:
<dependency> <groupId>com.mst.indexes</groupId> <artifactId>ui-automation-base</artifactId> <version>1.0.0-SNAPSHOT</version> <!-- 排除可能引入的高版本Selenium --> <exclusions> <exclusion> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium-java</artifactId> </exclusion> <exclusion> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium-api</artifactId> </exclusion> <exclusion> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium-chrome-driver</artifactId> </exclusion> </exclusions> </dependency> <!-- 显式声明Selenium版本,确保全局统一 --> <dependency> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium-java</artifactId> <version>3.141.59</version> </dependency>
方案3:升级到Selenium 4.x(彻底解决兼容问题)
若允许升级框架,将Selenium和WebDriverManager升级到兼容版本(支持Chrome 126):
<dependency> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium-java</artifactId> <version>4.11.0</version> </dependency> <dependency> <groupId>io.github.bonigarcia</groupId> <artifactId>webdrivermanager</artifactId> <version>5.6.0</version> <exclusions> <exclusion> <artifactId>slf4j-api</artifactId> <groupId>org.slf4j</groupId> </exclusion> </exclusions> </dependency>
升级后原有代码写法仍兼容,无需修改初始化逻辑。
内容的提问来源于stack exchange,提问作者Pratik Pathare
相关产品推荐
相关产品推荐

