JavaFX访问内部webkit文档

标签 javafx javafx-11 javafx-webengine gluonfx

我正在尝试从我的未命名模块 javafx 项目访问 javafx.web/com.sun.webkit.dom 。为此,我创建了一个类 com.sun.webkit.dom.DomMapper。 我在 IDE 中没有看到任何错误,但是当我使用 mvn clean javafx:ru​​n 运行它时,它会提示 -

Exception in thread "JavaFX Application Thread" java.lang.NoClassDefFoundError: com/sun/webkit/dom/DomMapper
....
Caused by: java.lang.ClassNotFoundException: com.sun.webkit.dom.DomMapper
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
...

这就是我的 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>
    <groupId> ... </groupId>
    <artifactId> ... </artifactId>
    <version> ... </version>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
        <exec.mainClass> .... </exec.mainClass>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-fxml</artifactId>
            <version>11</version>
        </dependency> 
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-controls</artifactId>
            <version>11</version>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-graphics</artifactId>
            <version>11</version>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-web</artifactId>
            <version>11</version>
        </dependency>
        <dependency>
            <groupId>org.jsoup</groupId>
            <artifactId>jsoup</artifactId>
            <version>1.14.3</version>
        </dependency> 
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.openjfx</groupId>
                <artifactId>javafx-maven-plugin</artifactId>
                <version>0.0.4</version>
                <configuration>
                    <options>
                        <option>--add-exports</option><option>javafx.web/com.sun.webkit.dom=ALL-UNAMED</option>
                        <option>--add-opens</option><option>javafx.web/com.sun.webkit.dom=ALL-UNAMED</option>
                    </options>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <compilerArgs>
                        <arg>--add-exports</arg><arg>javafx.web/com.sun.webkit.dom=ALL-UNAMED</arg>
                    </compilerArgs>
                </configuration>
            </plugin>
        </plugins>
    </build>

如果我使用 Maven 阴影插件,我就可以绕过这个问题。 我认为这与 JPMS 安全性的工作原理有关,但我不知道如何绕过它。我尝试了各种组合的添加导出和添加打开,但这对我没有帮助。 我做错了什么?

顺便说一句,我想将 WebKit DOM 映射到 JSoup dom 元素,因为它们为 CSS 选择器提供了一个很好的 API。

更新 我正在添加错误的附加堆栈跟踪

java.lang.reflect.InvocationTargetException
    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 javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:464)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:363)
    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 java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:1051)
Caused by: java.lang.RuntimeException: Exception in Application start method
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:900)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:195)
    at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: java.lang.NoClassDefFoundError: com/sun/webkit/dom/DomMapper
    at xyz.jphil.internal_browser.TestApp.start(TestApp.java:86)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:846)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:455)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:428)
    at java.base/java.security.AccessController.doPrivileged(Native Method)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:427)
    at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
    at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174)
    ... 1 more
Caused by: java.lang.ClassNotFoundException: com.sun.webkit.dom.DomMapper
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:583)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
    ... 10 more

最佳答案

这个问题的解决方案在于使用--patch-module。因为我添加了一个类 - com.sun.webkit.dom.DomMapper ,它完全由 JPMS 密封。我在 com.sun.webkit.dom.DomMapper 中添加 DomMapper 的原因是为了访问一些包私有(private)函数。

但是,我发现这很容易避免,因此我选择避免使用这些包私有(private)函数。有了这个 --patch-module 就不再需要了,根据 JPMS 文档,这也不是推荐的做法。现在解决方案更简单了。添加 --add Exports 就足够了(POM 中已经存在),我可以让它工作。

最后,例如使用 Maven Shade 插件将整个程序导出为 Farjar,也可以。我添加此内容仅供引用。

此答案基于 Jewelsea 和 Slaw 的评论和宝贵意见。 进一步说明:

  • 此示例显示 com.sun.webkit.dom 的公共(public)(尽管是内部)功能非常好,gist.github.com/jewelsea/6722397
  • 我通过在 com.sun.webkit.dom 中创建一个类而产生的问题称为 split-package - 阅读此处 How split packages are avoided in Java 9

关于JavaFX访问内部webkit文档,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72226094/

相关文章:

java - JavaFX11 的 javafx.stage.Stage 版本无效

java - 为什么 JavaFX 会自动调整图像大小?

java - 使用 WebEngine 的网页内容选择器

java - 如何在 JavaFX 中向 stackpane 上的同级发送事件

design-patterns - JavaFX 中的 MVVM。具有数据模型的控件

java - 任务只运行一次

java - 尝试使用 JavaFX 播放音频文件

JavaFX 模块化应用程序,未找到 java.lang.module.FindException : Module javafx. 控件(Java 11、Intellij)

javascript - 执行脚本Webview JavaFx

JavaFX - ListView 不填充 fxml 中的数据