无法在 java 11 中独立构建 Selenium

Can't build Selenium standalone in java 11

我正在 Eclipse 2018-12 中使用 Java11 构建一个 Java Selenium 独立应用程序,但我的构建失败了:

java.lang.module.FindException: Unable to derive module descriptor for \selenium-server-standalone-3.141.59.jar

我正在研究如何在最新版本的 java 中定义模块依赖关系,因为到目前为止我只使用版本 8。

模块-info.java:

module main {
    requires org.openqa.selenium.core;
}

主类:

package main;

import org.openqa.selenium.WebDriver;

public class DownloadDocuments {

    public static void main(String[] args) {
        System.out.println("hello!");
        WebDriver driver;
    }

}

使用模块时是否需要任何额外的配置步骤?

堆栈跟踪

java.lang.module.FindException: Unable to derive module descriptor for \selenium-server-standalone-3.141.59.jar
    at java.base/jdk.internal.module.ModulePath.readJar(ModulePath.java:647)
    at java.base/jdk.internal.module.ModulePath.readModule(ModulePath.java:330)
    at java.base/jdk.internal.module.ModulePath.scan(ModulePath.java:236)
    at java.base/jdk.internal.module.ModulePath.scanNextEntry(ModulePath.java:189)
    at java.base/jdk.internal.module.ModulePath.findAll(ModulePath.java:165)
    at java.base/java.lang.module.ModuleFinder.lambda$findAll(ModuleFinder.java:368)
    at java.lang.module.ModuleFinder$$Lambda.00000000DB437580.apply(Unknown Source)
    at java.base/java.util.stream.ReferencePipeline.accept(ReferencePipeline.java:271)
    at java.base/java.util.AbstractList$RandomAccessSpliterator.forEachRemaining(AbstractList.java:720)
    at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:499)
    at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:489)
    at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150)
    at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173)
    at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:241)
    at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:497)
    at java.base/java.lang.module.ModuleFinder.findAll(ModuleFinder.java:369)
    at java.base/java.lang.module.Resolver.findAll(Resolver.java:841)
    at java.base/java.lang.module.Resolver.bind(Resolver.java:223)
    at java.base/java.lang.module.Configuration.resolveAndBind(Configuration.java:304)
    at java.base/java.lang.module.ModuleDescriptor.resolveAndBind(ModuleDescriptor.java:2735)
    at java.base/jdk.internal.module.ModuleBootstrap.boot(ModuleBootstrap.java:337)
    at java.base/java.lang.ClassLoader.initializeClassLoaders(ClassLoader.java:217)
    at java.base/java.lang.Thread.initialize(Thread.java:422)
    at java.base/java.lang.Thread.<init>(Thread.java:153)
Caused by: java.lang.module.InvalidModuleDescriptorException: Provider class org.eclipse.jetty.http.Http1FieldPreEncoder not in module
    at java.base/jdk.internal.module.ModulePath.deriveModuleDescriptor(ModulePath.java:554)
    at java.base/jdk.internal.module.ModulePath.readJar(ModulePath.java:643)
    ... 23 more

看这里https://github.com/SeleniumHQ/selenium/wiki/Building-WebDriver

Java JDK 8(请注意,当前不支持版本 9 和 10 构建 Selenium)。如果您的计算机上没有它,请从 Oracle 站点下载它。

这是由于 .jar 文件中的错误。它包含一个 META-INF/services/org.eclipse.jetty.http.HttpFieldPreEncoder 条目,根据 jar service provider interface specification,该条目必须在实现接口 org.eclipse.jetty.http.HttpFieldPreEncoder.[= 的同一个 .jar 文件中包含 class 的名称18=]

但是,如异常所述,该服务描述符文件包含 org.eclipse.jetty.http.Http1FieldPreEncoder,一个在 .jar 文件中不存在的 class。

但是,.jar 中有一个 org.seleniumhq.jetty9.http.Http1FieldPreEncoder class。

解决此问题的最简单方法是:

  • 将整个 .jar 解压到临时目录。
  • 更改 META-INF/services/org.eclipse.jetty.http.HttpFieldPreEncoder 使其包含单行 org.seleniumhq.jetty9.http.Http1FieldPreEncoder.
  • 从更改的内容创建一个新的 .jar 文件。

如果你不在Windows,你可以在命令行上做:

mkdir -p META-INF/services
echo org.seleniumhq.jetty9.http.Http1FieldPreEncoder > META-INF/services/org.eclipse.jetty.http.HttpFieldPreEncoder
zip -u -m selenium-server-standalone-3.141.59.jar META-INF/services/org.eclipse.jetty.http.HttpFieldPreEncoder
rm -r META-INF

遇到同样的问题,在classpath下定义所有的jar就可以了。

对我来说,我只需要将库中构建路径中的 selenium.jar 从模块路径移动到类路径。 希望对你有帮助。