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 依赖的同一模块中:
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 文件中注册:
@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 使 Map 或 Set 可访问,也请为 java.util.Map 和 java.util.Set 添加相应条目。
如果您向 JavaScript 暴露一个接口,然后传入具体实现,请同时注册可访问的接口和您在运行时注入的具体实现类。
有关 @JsAccessible、JsAccessibleTypes 和 JavaScript 桥接行为的更多详情,请参阅 JavaScript 指南。
构建原生镜像
将 jxbrowser-native-image 放入类路径并就位应用程序元数据后,使用您常规的原生镜像工作流构建可执行文件。
JxBrowser 特定的工作仅限于:
- 在原生镜像构建期间将
jxbrowser-native-image保留在类路径中; - 保持所有 JxBrowser 工件版本一致;
- 为您应用程序中可被 JavaScript 访问的类型添加您自己的可达性元数据。
如果您的项目已经使用 GraalVM Native Build Tools 插件,则无需额外的 JxBrowser 插件来支持原生镜像。只需额外的 JxBrowser 工件和您的应用程序元数据即可。