目录

Native Image

本指南介绍如何将 JxBrowser 应用程序构建为 GraalVM 原生镜像,需要添加哪些 JxBrowser 特定依赖,以及您仍需在自己的应用程序中进行哪些配置。

JxBrowser 通过 jxbrowser-native-image 工件支持 GraalVM Native Image。

jxbrowser-native-image 工件提供了 JxBrowser 本身所需的可达性元数据。换句话说,您无需手动为 JxBrowser 内部准备反射或 JNI 配置。

可达性元数据以 GraalVM 23 中引入的统一 reachability-metadata.json 格式提供。

添加可达性数据 

如果您使用 JxBrowser Gradle 插件,请将 jxbrowser-native-image 添加到声明常规 JxBrowser 依赖的同一模块中:

Gradle
Maven
dependencies {
    implementation(jxbrowser.currentPlatform)
    implementation(jxbrowser.swing)
    implementation(jxbrowser.nativeImage)
}
<dependencies>
    ...
    <dependency>
        <groupId>com.teamdev.jxbrowser</groupId>
        <artifactId>jxbrowser-native-image</artifactId>
        <version>9.0.0</version>
    </dependency>
</dependencies>

如果您不使用 JxBrowser Gradle 插件,请手动添加 com.teamdev.jxbrowser:jxbrowser-native-image:9.0.0,并将其版本与其他 JxBrowser 工件保持同步。

如果您的应用程序使用 JavaFX、SWT 或 Compose Desktop,请同时保留相应的 UI 工具包依赖。GraalVM 工件不会替换常规的 JxBrowser 模块,而是对其进行补充。

对于 Swing 和 JavaFX 桌面应用程序,请使用支持桌面原生镜像构建的 GraalVM 发行版。我们使用 Liberica Native Image Kit (NIK) 对 JxBrowser 进行测试。

可被 JavaScript 访问的类型 

如果您的应用程序将 Java 或 Kotlin 对象暴露给 JavaScript,JxBrowser 将在运行时使用反射来访问它们。因此,原生镜像构建需要额外一步来使可被 JavaScript 访问的类型正常工作。

在常规应用程序中,只需使用 @JsAccessible 标记成员,或通过 JsAccessibleTypes 使类型可访问即可。

在原生镜像中,相同的应用程序特定类型还必须在您应用程序自己的 reachability-metadata.json 文件中注册:

Java
Kotlin
@JsAccessible
public final class Bridge {
    public String sayHello(String name) {
        return "Hello " + name + "!";
    }
}

public final class App {
    public static void main(String[] args) {
        var engine = Engine.newInstance(HARDWARE_ACCELERATED);
        var browser = engine.newBrowser();
        browser.set(InjectJsCallback.class, params -> {
            var window = params.frame().executeJavaScript("window");
            window.putProperty("bridge", new Bridge());
            return InjectJsCallback.Response.proceed();
        });
    }
}
class Bridge {
    @JsAccessible
    fun sayHello(name: String) = "Hello $name!"
}

fun main() {
    val engine = Engine.newInstance(HARDWARE_ACCELERATED)
    val browser = engine.newBrowser()
    browser.register(InjectJsCallback { params ->
        val window = params.frame().executeJavaScript<JsObject>("window")
        window?.putProperty("bridge", Bridge())
        InjectJsCallback.Response.proceed()
    })
}

将 Bridge 类型添加到您应用程序的 reachability-metadata.json 文件中:

{
  "reflection": [
    {
      "type": "com.example.Bridge",
      "methods": [
        {
          "name": "sayHello",
          "parameterTypes": ["java.lang.String"]
        }
      ]
    }
  ]
}

注册每个您暴露给 JavaScript 的应用程序或第三方类型。如果您通过 JsAccessibleTypes 使 MapSet 可访问,也请为 java.util.Mapjava.util.Set 添加相应条目。

如果您向 JavaScript 暴露一个接口,然后传入具体实现,请同时注册可访问的接口和您在运行时注入的具体实现类。

有关 @JsAccessibleJsAccessibleTypes 和 JavaScript 桥接行为的更多详情,请参阅 JavaScript 指南。

构建原生镜像 

jxbrowser-native-image 放入类路径并就位应用程序元数据后,使用您常规的原生镜像工作流构建可执行文件。

JxBrowser 特定的工作仅限于:

  • 在原生镜像构建期间将 jxbrowser-native-image 保留在类路径中;
  • 保持所有 JxBrowser 工件版本一致;
  • 为您应用程序中可被 JavaScript 访问的类型添加您自己的可达性元数据。

如果您的项目已经使用 GraalVM Native Build Tools 插件,则无需额外的 JxBrowser 插件来支持原生镜像。只需额外的 JxBrowser 工件和您的应用程序元数据即可。