线程“主”java.lang.NoClassDefFoundError 中的异常:org/openqa/selenium/WebDriver

Posted

技术标签:

【中文标题】线程“主”java.lang.NoClassDefFoundError 中的异常:org/openqa/selenium/WebDriver【英文标题】:Exception in thread "main" java.lang.NoClassDefFoundError: org/openqa/selenium/WebDriver 【发布时间】:2018-05-29 03:24:48 【问题描述】:

我在 pom.xml 中添加了最新的 Selenium 依赖项

<dependency>
    <groupId>org.seleniumhq.selenium</groupId>
    <artifactId>selenium-java</artifactId>
    <version>3.7.1</version>
</dependency>

我跑了 mvn 干净安装 在我的 pom.xml 目录中,我还根据 Selenium 文档在我的应用程序类中导入了正确的类

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;

但是,当我尝试运行我的主要方法时,我收到以下错误

Exception in thread "main" java.lang.NoClassDefFoundError: 
org/openqa/selenium/WebDriver

我查看了 ~/.m2/repository 文件夹,但没有看到 openqa 文件夹,而是看到了 seleniumhq 文件夹。

为什么 maven 不安装 openqa 文件夹,为什么文档说要从 org.openqa 导入...而我的 jar 存储库中从来不存在。我很困惑,我只想能够成功导入 selenium Webdriver,同时将它放在我的本地存储库中。

【问题讨论】:

您可能犯了与***.com/q/58882789/1525602 的OP 完全相同的错误,即。 e.运行程序时,类路径中没有所有 jar 依赖项(包括传递的依赖项!)。所以这里有一个关键问题:你如何运行你的程序?。因为根据您想要运行它的方式(从 IDE、从命令行、从使用 mvn exec 的命令行、作为服务器上的 servlet...)来构建应用程序包的方法太多了。 【参考方案1】:

首先,正确检查您的程序是否具有所有重要的依赖项。 其次,我在运行maven项目时遇到了类似的错误:

Caused by: java.lang.NoClassDefFoundError: org/openqa/selenium/javascriptExecutor

这个问题是因为插件不合适,因为我测试了不同版本的 Selenium,它没有帮助我。

所以当我换了maven-jar-plugin:

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.1.0</version>
 <configuration>
   <archive>
        <manifest>
             <addClasspath>true</addClasspath>
             <classpathPrefix>lib/</classpathPrefix>
             <mainClass>your_main_class</mainClass>
        </manifest>
   </archive>
 </configuration>
</plugin>

maven-shade-plugin插件:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <version>3.0.0</version>
    <executions>
       <execution>
            <phase>package</phase>
            <goals>
               <goal>shade</goal>
            </goals>
            <configuration>
                 <transformers>
                    <transformer 
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                        <mainClass>your_main_class</mainClass>
                    </transformer>
                 </transformers>
             </configuration>
       </execution>
    </executions>
</plugin>

问题消失了。 插件的区别你可以找here.


此外,有时我们会升级我们的库,即使方法名称相同。由于版本不同,当一个库与此类升级不兼容时,我们会在运行时收到 NoClassDefFoundErrorNoSuchMethodError

Java 构建工具和 IDE 还可以生成依赖性报告,告诉您哪些库依赖于该 JAR。大多数情况下,识别和升级依赖于旧 JAR 的库可以解决问题。


总结一下:

尝试更改 Selenium 的版本,如果它包含所有依赖项; 如果没有,请尝试添加必要的依赖项; 尝试检查 maven 文件夹是否有特定错误; 如果上面没有任何帮助,请尝试使用插件。

【讨论】:

太棒了!这立即解决了我的问题。我明白问题出在哪里,但我不明白为什么 mvn 不将运行时所需的所有依赖项打包到 jar 中。也许一个更好的 jar 插件配置可以指定所需的内容......我也会尝试【参考方案2】:

在 Eclipse IDE 中遇到此错误。在 Eclipse 中转到项目属性,在 Java Build Path 中,只需在 Classpath 中添加 selenium jar 而不是 Modulepath。然后在顶部的 Project 选项卡下执行 Clean 以删除较早的 buiid,然后执行 Run。

【讨论】:

【参考方案3】:

NoClassDefFoundError

Java 虚拟机 无法在运行时找到编译时可用的特定类时,Java 中的

NoClassDefFoundError 就会发生。例如,如果我们从一个类解析了一个方法调用或访问了一个类的任何静态成员,并且该类在运行时不可用,那么 JVM 将抛出 NoClassDefFoundError

您看到的错误是:

Exception in thread "main" java.lang.NoClassDefFoundError: 
org/openqa/selenium/WebDriver

这清楚地表明 Selenium 正在尝试在运行时从 org/openqa/selenium/WebDriver 解析特定的类,而 org/openqa/selenium/WebDriver 不再可用。

正如您提到的查看~/.m2/repository 文件夹,Selenium v​​3.7.1(在 Windows 上)的 maven 文件夹结构如下:

C:\Users\<user_name>\.m2\repository\org\seleniumhq\selenium\selenium-java\3.7.1

因此,当您看到 seleniumhq 文件夹时,这是意料之中的。


出了什么问题:

从上面提到的所有点来看,很明显相关的 ClassMethods 是从一个 Compile Time 来源解决的,而该来源在此期间不可用运行时间

如果存在多个通过 JDK / Maven / Gradle 解析类和方法的来源,则会出现这种情况。


解决办法:

以下是解决NoClassDefFoundError的几个步骤:

使用构建工具时,例如MavenGradle,从 Java 构建路径删除所有外部 JARMavenGradle 将下载并解析所有必需的依赖项。 如果在 Java 项目 中使用 Selenium JAR,则在 Java 构建路径 中仅添加所需的 External JAR 和删除未使用的。 在使用 Maven 时,请使用 &lt;artifactId&gt;selenium-java&lt;/artifactId&gt;&lt;artifactId&gt;selenium-server&lt;/artifactId&gt;。避免同时使用两者。 从 pom.xml 中删除不需要的其他 &lt;dependency&gt; 定期清理您的 IDE 中的 Project Workspac,仅用于构建具有所需依赖项的项目。 使用 CCleane 工具定期清除操作系统的琐事。 当您执行 Maven 项目时,请始终执行maven cleanmaven install 然后maven test

【讨论】:

我认为这个答案的第一部分“什么是 NoClassDefFoundError”是非常正确的。但恐怕第二部分“出了什么问题”包含了许多可能不是重点的期望和建议。喜欢使用CCleaner 或总是使用maven ... 来命名一些...我认为这会让没有经验的Maven 用户感到困惑。【参考方案4】: org.openqa.seleniumselenium-api-version.jar文件夹下seleniumhq\selenium\selenium-api下的包。 org.openqa.selenium.firefoxseleniumhq\selenium\selenium-firefox-driver文件夹下selenium-firefox-driver-version.jar中的包。

所以没有openqa文件夹,只是seleniumhq文件夹下的包名,你应该检查一下这些jar。

如果没有项目结构和代码细节,很难说是什么导致了NoClassDefFoundError 异常。该异常与ClassNotFoundException 不同。也许这个答案https://***.com/a/5756989/5374508 会有所帮助。

【讨论】:

【参考方案5】:

您是使用 IDE 还是从命令行工作?例如,在 Eclipse 中,您可以通过右键单击您的项目、转到 Maven 菜单项然后选择更新项目来强制下载所有依赖项。然后选中“强制更新快照/发布”复选框。

如果你是从命令行打开:

mvn clean install -U

来自您的项目路径。

【讨论】:

OP 写道,Maven 构建和编译是好的。因此,可能无需按照您的建议强制 Maven 重新下载工件(jar-s 等)。【参考方案6】:

对我有用的是将此依赖项添加到 pom.xml:

    <dependency>
        <groupId>com.google.guava</groupId>
        <artifactId>guava</artifactId>
        <version>25.0-jre</version>
    </dependency>

【讨论】:

我想这没有必要。因为这个依赖已经存在,虽然在版本 23 中。它是传递依赖之一,你可以在 mvnrepository page 看到,例如。或者你真的说使用另一个 Guava 版本就可以了?

以上是关于线程“主”java.lang.NoClassDefFoundError 中的异常:org/openqa/selenium/WebDriver的主要内容,如果未能解决你的问题,请参考以下文章

主线程啥都没做,就会等待子线程结束。这是为啥?

Android 异步操作Android 线程切换 ( 判定当前线程是否是主线程 | 子线程中执行主线程方法 | 主线程中执行子线程方法 )

子线程怎么不阻塞主线程

QT中UI主窗口如何与子线程相互传递参数

java 子线程 回调 主线程

C++怎么在主线程中使用子线程的数据? 比如说主线程中有一个数组,如何在子线程中调用这个数组