Chromium
本指南将介绍如何使用 JxBrowser 使用的 Chromium 构建。
您无需在目标环境中安装 Chromium 或 Google Chrome 即可使用 JxBrowser。JxBrowser 使用并部署其自有的 Chromium 构建。
二进制文件
每个支持平台的 Chromium 二进制文件位于相应的 JxBrowser JAR 中:
jxbrowser-win32-8.13.0.jar– 适用于 Windows 32 位的 Chromium 二进制文件。jxbrowser-win64-8.13.0.jar– 适用于 Windows 64 位的 Chromium 二进制文件。jxbrowser-mac-8.13.0.jar– 适用于 macOS 的 Chromium 二进制文件。jxbrowser-mac-arm-8.13.0.jar– 适用于 macOS Apple Silicon 的 Chromium 二进制文件。jxbrowser-linux64-8.13.0.jar– 适用于 Linux 64 位的 Chromium 二进制文件。jxbrowser-linux64-arm-8.13.0.jar– 适用于 Linux ARM 64 位的 Chromium 二进制文件。
位置
默认情况下,JxBrowser 会将 Chromium 二进制文件提取到 Linux 和 macOS 上的用户临时目录,以及 Windows 上的 AppData\Local\JxBrowser 目录。
以下是如何更改 JxBrowser 提取二进制文件的目录的方法:
使用
jxbrowser.chromium.dir系统属性。它可以通过
System.setProperty()方法来设置:JavaKotlinSystem.setProperty("jxbrowser.chromium.dir", "Users/Me/.jxbrowser");System.setProperty("jxbrowser.chromium.dir", "Users/Me/.jxbrowser")或者通过 JVM 参数来设置:
-Djxbrowser.chromium.dir="Users/Me/.jxbrowser"通过在创建
Engine时使用EngineOptions:JavaKotlinvar engine = Engine.newInstance( EngineOptions.newBuilder(renderingMode) .chromiumDir(Paths.get("Users/Me/.jxbrowser")) .build() );val engine = Engine(renderingMode) { chromiumDir = Path("Users/Me/.jxbrowser") }
该目录路径可以是相对路径也可以是绝对路径。
目录不能位于网络驱动器上。
验证
每个 JxBrowser 版本仅与其相同版本的二进制文件兼容。例如, JxBrowser 的 8.13.0.1 版本无法使用来自 JxBrowser 8.13.0 的二进制文件。
为确保 Chromium 二进制文件与当前的 JxBrowser 版本兼容,库会对这些二进制文件进行验证。
提取
默认情况下,当首次创建 Engine 时,JxBrowser 会从相应的 JAR 文件中提取二进制文件。如果您需要提前提取二进制文件,请使用以下代码:
// 使用默认目录。
ChromiumBinaries.deliverToDefaultDirectory();
// 或者使用任意目录。
ChromiumBinaries.deliverTo(Paths.get("/path/to/binaries"));
// 使用默认目录。
ChromiumBinaries.deliverToDefaultDirectory()
// 或者使用任意目录。
ChromiumBinaries.deliverTo(Path("/path/to/binaries"))
如果兼容的二进制文件已经提取过,JxBrowser 将不会再次提取它们。否则,JxBrowser 会再次提取二进制文件并覆盖现有文件。
自定义二进制文件交付
从 JxBrowser 7.35 开始,开发者可以完全控制 Chromium 二进制文件到环境的交付过程。这项功能是为高级用例设计的,例如从网络下载二进制文件,或使用自定义压缩算法:
// 使用默认目录。
ChromiumBinaries.deliverToDefaultDirectory(new MyDelivery());
// 或使用任意目录。
ChromiumBinaries.deliverTo(chromiumDir, new MyDelivery());
// 使用默认目录。
ChromiumBinaries.deliverToDefaultDirectory(MyDelivery())
// 或使用任意目录。
ChromiumBinaries.deliverTo(chromiumDir, MyDelivery())
准备二进制文件
本节将说明如何为自定义交付准备包含二进制文件的归档包。请针对应用程序支持的每个平台重复此过程。
首先,从 JxBrowser 发行包中提取二进制文件:
克隆快速开始项目。
使用自定义 Chromium 目录运行项目:
./gradlew run -Djxbrowser.chromium.dir=/path/to/chromium -Djxbrowser.license.key=...该命令会将当前平台对应的 Chromium 二进制文件提取到指定目录:
> ls /path/to/chromium Chromium.app chromium.version libawt_toolkit.dylib libipc.dylib ...
其次,打包二进制文件。本示例使用 ZIP 格式:
Compress-Archive -Path C:\path\to\chromium\* -DestinationPath binaries.zip
cd /path/to/chromium/
# -y 参数用于保留二进制文件中使用的符号链接。
zip -r -y ../binaries.zip .
最后,将 binaries.zip 文件上传到您的应用程序可下载的位置。
交付二进制文件
本节提供一个简单示例,展示如何通过自定义交付方式下载已准备好的二进制文件归档包:
import static com.teamdev.jxbrowser.os.Environment.isWindows;
...
class MyDelivery implements BinariesDelivery {
private static final String URL = "http://.../binaries.zip";
@Override
public void deliverTo(Path chromiumDir) {
var tempZip = download(URL);
unpack(tempZip, chromiumDir);
}
private Path download(String url) {
var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder()
.uri(URI.create(url))
.GET()
.build();
try {
var tempZip = createTempFile("chromium-", ".zip");
client.send(request, HttpResponse.BodyHandlers.ofFile(tempZip));
return tempZip;
} catch (Exception e) {
throw new IllegalStateException(e);
}
}
private void unpack(Path archive, Path directory) {
var command = isWindows()
? new String[]{
"powershell", "-Command", "Expand-Archive",
"-Path", archive.toString(),
"-DestinationPath", directory.toString()}
: new String[]{
"unzip", archive.toString(),
"-d", directory.toString()};
try {
var process = Runtime.getRuntime().exec(command);
process.waitFor();
} catch (Exception e) {
throw new IllegalStateException(e);
}
}
}
import com.teamdev.jxbrowser.os.Environment.isWindows
...
class MyDelivery : BinariesDelivery {
override fun deliverTo(chromiumDir: Path) {
val tempZip = download(URL)
unpack(tempZip.toString(), chromiumDir.toString())
}
private fun download(url: String): Path {
val client = HttpClient.newHttpClient()
val request = HttpRequest.newBuilder()
.uri(URI.create(URL))
.GET()
.build()
val tempZip = createTempFile(suffix = ".zip")
client.send(request, HttpResponse.BodyHandlers.ofFile(tempZip))
return tempZip
}
private fun unpack(archive: String, directory: String) {
val command = if (isWindows()) {
arrayOf(
"powershell", "-Command", "Expand-Archive",
"-Path", archive, "-DestinationPath", directory
)
} else {
arrayOf("unzip", archive, "-d", directory)
}
val process = Runtime.getRuntime().exec(command)
process.waitFor()
}
companion object {
private const val URL = "http://.../binaries.zip"
}
}
沙盒
JxBrowser 在 Windows、Linux 和 macOS 系统上支持 Chromium 沙盒功能。沙盒默认处于启用状态,可为 Chromium 子进程提供重要的隔离保护和安全保障。
可以通过相应的 Engine 选项来禁用沙盒:
var engine = Engine.newInstance(
EngineOptions.newBuilder(renderingMode)
.disableSandbox()
.build()
);
val engine = Engine(renderingMode) {
sandboxDisabled = true
}
禁用沙盒会显著降低安全性。如果您的应用程序加载不受信任的 HTML,例如来自外部来源的内容或用户生成的输入,请勿禁用沙盒。这样做可能会使您的系统面临严重的安全风险。
Linux
Chromium 依赖用户命名空间(user namespaces) 来为其子进程提供沙盒隔离。
当该功能不可用时,JxBrowser 无法启动 Chromium,并会在 Engine 初始化阶段抛出 SandboxNotSupportedException 异常。
在 Debian 10 中,默认情况下,非特权用户的用户命名空间处于禁用状态。Ubuntu 也支持通过内核参数来切换用户命名空间。在这些系统中,您可以使用以下命令启用用户命名空间:
sudo sysctl -w kernel.unprivileged_userns_clone=1
echo 'kernel.unprivileged_userns_clone=1' | sudo tee -a /etc/sysctl.d/99-enable-unprivileged-userns.conf
在 Ubuntu 23.10 及更高版本中,AppArmor 会进一步限制用户命名空间。要放宽此限制,请配置以下参数:
sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0
echo 'kernel.apparmor_restrict_unprivileged_userns=0' | sudo tee -a /etc/sysctl.d/99-enable-unprivileged-userns.conf
其他 Linux 发行版默认启用用户命名空间,无需额外配置。
如果您无法修改环境配置以启用用户命名空间,您可以禁用 Chromium 沙盒。这种方法会显著降低安全性,应仅作为最后的解决办法。
网络流量
Chromium 是一个复杂的软件,包含多个组件。一些组件可能会因发送统计数据、同步、优化、数据下载等目的而在后台进行网络活动。
本节将介绍可能会产生额外网络流量的组件,并说明如何禁用它们。
优化指南服务
该组件是 Google 提供的 Chromium 服务,旨在帮助开发者提升应用性能和效率。它基于设备的硬件、软件和用户习惯,提供个性化的优化建议和运行时配置数据。在开发 Android 应用时,这项服务尤其重要。启动时,该服务会从 Google Web 服务获取优化模型。
JxBrowser 已禁用此组件,因此不会从 Google Web 服务获取任何数据。
拼写检查器
默认情况下,该组件不会向外部 Web 服务器发送任何请求。它使用本地字典进行拼写检查。然而,如果某些语言的字典在本地不可用,它可能会向 Google Web 服务发送请求以获取相应的字典。
如果您不需要拼写检查功能,并希望禁止与其相关的任何网络活动,可按照拼写检查器指南中描述的方法禁用该功能。
翻译排序器
该组件用于判断是否应向用户提供翻译提示。Chromium 会下载用于语言识别的排序模型。
JxBrowser 已禁用此组件,因此不会向外部 Web 服务器请求任何数据。
媒体投放
该组件负责将媒体内容投放到支持 Chromecast 的设备。当 Chromium 启动时,组件会在本地网络中发送多播请求,以发现可用的投放设备。
默认情况下,Chromecast 功能已禁用,不会产生网络流量。如果需要启用此功能,可以在初始化 Engine 实例时进行配置,具体方法请参考媒体指南。
组件更新器
该组件用于更新 Chromium 中的其他组件。默认情况下,组件更新器处于禁用状态。若启用专有编解码器,则该组件将自动启用,以更新相关的内部组件。一旦启用,您可能会看到访问 https://update.googleapis.com/service/update2/json 的请求。
DNS Over HTTPS (DoH)
是 Chromium 中默认的 DNS 解析协议。Chromium 会检查系统 DNS 提供商是否支持 DoH,并尝试识别。如果系统 DNS 配置了 Google Public DNS 或其他支持 DoH 的提供商,Chromium 将自动切换到相应的 DoH 服务。此时,Chromium 将向可信的 DoH 服务器(如 google.dns)发送请求以解析 DNS。
在 JxBrowser 中,DoH 默认启用。如果您希望禁用它,请使用以下代码:
var engine = Engine.newInstance(
EngineOptions.newBuilder(renderingMode)
.disableDnsOverHttps()
.build()
);
禁用 DoH 后,Chromium 将根据操作系统的 DNS 配置,使用未加密的系统 DNS(UDP 或 TCP)进行解析。
品牌自定义
JxBrowser 使用自己的 Chromium 构建,该构建作为库的一部分随附分发。Chromium 在一个名为 Chromium 的独立本地进程中运行。该进程具有默认的图标、版本、描述和版权信息。

当您将 JxBrowser 集成到您的 Java 桌面应用程序中时,您可能希望自定义 Chromium 进程的名称、图标、版本等,并使用您自己的品牌,以提升用户体验。通过将其自定义为与您的应用程序品牌匹配,您的用户就不会对任务管理器中显示的陌生 Chromium 进程感到困惑。
要自定义 Chromium 进程,请使用开源的 Chromium Branding 命令行工具。有关如何使用该工具的说明,请参阅 README.md 指南。
配置 JxBrowser 使用自定义品牌的 Chromium 二进制文件时,只需在初始化 Engine 实例时指定自定义 Chromium 的路径:
var engine = Engine.newInstance(
EngineOptions.newBuilder(renderingMode)
.chromiumDir(Paths.get("path/to/branded/Chromium"))
.build()
);
val engine = Engine(renderingMode) {
chromiumDir = Path("path/to/branded/Chromium")
}
在自定义 Chromium 进程名称与图标文章中,您可以找到有关如何在 Windows 上自定义 Chromium 进程名称、图标、版本和其他品牌信息的分步指南。