fix(ffi): Replace libloading with jvm-getter for getting a JVM

The `libloading` approach only works on Android 12+
This commit is contained in:
Jorge Martín
2026-03-30 10:11:39 +02:00
committed by Jorge Martin Espinosa
parent 83c6a7fdf4
commit e65d4c44b4
4 changed files with 117 additions and 37 deletions
Generated
+100 -13
View File
@@ -2169,6 +2169,17 @@ dependencies = [
"scroll",
]
[[package]]
name = "goblin"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "daa0a64d21a7eb230583b4c5f4e23b7e4e57974f96620f42a7e75e08ae66d745"
dependencies = [
"log",
"plain",
"scroll",
]
[[package]]
name = "growable-bloom-filter"
version = "2.1.1"
@@ -2910,6 +2921,18 @@ dependencies = [
"serde_json",
]
[[package]]
name = "jvm-getter"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a9353d43a802ba22de0de749f4aa51f3414a6a9b5037559eaac65584db65218"
dependencies = [
"goblin 0.9.3",
"jni-sys",
"libc",
"windows-sys 0.60.2",
]
[[package]]
name = "konst"
version = "0.3.9"
@@ -2957,16 +2980,6 @@ version = "0.2.175"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543"
[[package]]
name = "libloading"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "754ca22de805bb5744484a5b151a9e1a8e837d5dc232c2d7d8c2e3492edc8b60"
dependencies = [
"cfg-if",
"windows-link 0.2.1",
]
[[package]]
name = "libm"
version = "0.2.15"
@@ -3444,8 +3457,8 @@ dependencies = [
"futures-executor",
"futures-util",
"jni",
"jvm-getter",
"language-tags",
"libloading",
"log-panics",
"matrix-sdk",
"matrix-sdk-base",
@@ -6645,7 +6658,7 @@ dependencies = [
"cargo_metadata",
"fs-err",
"glob",
"goblin",
"goblin 0.8.2",
"heck",
"indexmap",
"once_cell",
@@ -7351,6 +7364,15 @@ dependencies = [
"windows-targets 0.52.6",
]
[[package]]
name = "windows-sys"
version = "0.60.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb"
dependencies = [
"windows-targets 0.53.5",
]
[[package]]
name = "windows-sys"
version = "0.61.2"
@@ -7399,13 +7421,30 @@ dependencies = [
"windows_aarch64_gnullvm 0.52.6",
"windows_aarch64_msvc 0.52.6",
"windows_i686_gnu 0.52.6",
"windows_i686_gnullvm",
"windows_i686_gnullvm 0.52.6",
"windows_i686_msvc 0.52.6",
"windows_x86_64_gnu 0.52.6",
"windows_x86_64_gnullvm 0.52.6",
"windows_x86_64_msvc 0.52.6",
]
[[package]]
name = "windows-targets"
version = "0.53.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3"
dependencies = [
"windows-link 0.2.1",
"windows_aarch64_gnullvm 0.53.1",
"windows_aarch64_msvc 0.53.1",
"windows_i686_gnu 0.53.1",
"windows_i686_gnullvm 0.53.1",
"windows_i686_msvc 0.53.1",
"windows_x86_64_gnu 0.53.1",
"windows_x86_64_gnullvm 0.53.1",
"windows_x86_64_msvc 0.53.1",
]
[[package]]
name = "windows-threading"
version = "0.1.0"
@@ -7433,6 +7472,12 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53"
[[package]]
name = "windows_aarch64_msvc"
version = "0.42.2"
@@ -7451,6 +7496,12 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_aarch64_msvc"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006"
[[package]]
name = "windows_i686_gnu"
version = "0.42.2"
@@ -7469,12 +7520,24 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
[[package]]
name = "windows_i686_gnu"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3"
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_gnullvm"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c"
[[package]]
name = "windows_i686_msvc"
version = "0.42.2"
@@ -7493,6 +7556,12 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_i686_msvc"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2"
[[package]]
name = "windows_x86_64_gnu"
version = "0.42.2"
@@ -7511,6 +7580,12 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnu"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.42.2"
@@ -7529,6 +7604,12 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1"
[[package]]
name = "windows_x86_64_msvc"
version = "0.42.2"
@@ -7547,6 +7628,12 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "windows_x86_64_msvc"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650"
[[package]]
name = "winnow"
version = "0.6.20"
+3
View File
@@ -8,6 +8,9 @@ All notable changes to this project will be documented in this file.
### Bug Fixes
- Fix devices on Android 11 crashing because the SDK could not be initialized using `libloading`
to get a reference to the JVM. Replaced `libloading` with `jvm-getter`, which works like a
compatibility layer. ([#6370](https://github.com/matrix-org/matrix-rust-sdk/pull/6370))
- Added `android_platform.rs` for fixing the `rustls` integration on Android, which was broken.
([#6306](https://github.com/matrix-org/matrix-rust-sdk/pull/6306))
- [**breaking**] `OtherState` properly supports redacted events that still have fields in the
+2 -2
View File
@@ -128,10 +128,10 @@ paranoid-android = { version = "0.2.2", default-features = false }
jni = "0.21.1"
# Used to access the credential storage on Android
rustls-platform-verifier = "0.6.2"
# Used to avoid having to call an exposed JNI call from the Android client to initialize `rustls-platform-verifier`
libloading = "0.9.0"
# Needed for intializing and keeping the JavaVM reference around
once_cell = "1.21.4"
# Gobley's jvm-getter is used to get a JVM pointer from all Android versions
jvm-getter = "0.1.0"
[dev-dependencies]
similar-asserts.workspace = true
@@ -1,8 +1,8 @@
use std::error::Error;
use std::{error::Error, mem::MaybeUninit};
use jni::{
errors::JniError,
sys::{jint, jsize, JavaVM},
sys::{JavaVM as RawJavaVM, JNI_OK},
};
use tracing::debug;
@@ -34,30 +34,20 @@ pub(crate) fn init() {
});
}
type JniGetCreatedJavaVms =
unsafe extern "system" fn(_: *mut *mut JavaVM, _: jsize, _: *mut jsize) -> jint;
const JNI_GET_JAVA_VMS_NAME: &[u8] = b"JNI_GetCreatedJavaVMs";
fn get_java_vm() -> Result<jni::JavaVM, Box<dyn Error>> {
// Use libloading to avoid having to create and expose a JNI function and call
// it from the Android side.
let library = libloading::os::unix::Library::this();
let get_created_java_vms: JniGetCreatedJavaVms =
unsafe { *library.get(JNI_GET_JAVA_VMS_NAME)? };
debug!("Getting a JVM pointer");
#[allow(non_snake_case)]
let JNI_GetCreatedJavaVMs = unsafe {
jvm_getter::find_jni_get_created_java_vms().expect("Failed to find JNI_GetCreatedJavaVMs")
};
let mut java_vms: [*mut JavaVM; 1] = [std::ptr::null_mut() as *mut JavaVM];
let mut vm_count: i32 = 0;
let ok = unsafe { get_created_java_vms(java_vms.as_mut_ptr(), 1, &mut vm_count) };
if ok != jni::sys::JNI_OK {
return Err("Failed to get JavaVM".into());
}
if vm_count != 1 {
return Err(format!("Invalid JavaVM count: {vm_count}").into());
let mut vm: MaybeUninit<*mut RawJavaVM> = MaybeUninit::uninit();
let status = unsafe { JNI_GetCreatedJavaVMs(vm.as_mut_ptr(), 1, &mut 0) };
if status != JNI_OK {
panic!("no JavaVM was found by JNI_GetCreatedJavaVMs");
}
let jvm = unsafe { jni::JavaVM::from_raw(java_vms[0]) }?;
Ok(jvm)
unsafe { jni::JavaVM::from_raw(vm.assume_init()).map_err(|e| e.into()) }
}
fn init_rustls_platform_verifier(env: &mut jni::JNIEnv<'_>) -> jni::errors::Result<()> {