1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
// Copyright (c) 2025 Gobley Contributors.
//! > ⚠️ This library depends on implementation details of Android, not its public APIs. Use at your
//! > own risk.
//!
//! A tiny `no_std` library for finding [`JNI_GetCreatedJavaVMs()`] on Android 24 to 30.
//!
//! [`JNI_GetCreatedJavaVMs()`] is a JNI function that returns the list of Java VM instances that
//! have been created during runtime. Unfortunately, on Android API level 30 or lower,
//! [`JNI_GetCreatedJavaVMs()`] is **not** one of the public APIs. Therefore, the recommended way by
//! the official Android documentation is to use `JNI_OnLoad()`, which has a `JavaVM` parameter.
//!
//! This is painful for cross-platform library developers, especially when the OS feature they want
//! to use is coupled with Java on Android, as they have to provide a way to pass `JNIEnv` to the
//! library. By using [`JNI_GetCreatedJavaVMs()`], you can retrieve the `JavaVM` instance, and you
//! can even create `JNIEnv` instances for threads created on the Rust side.
//!
//! With `jvm-getter`, libraries can provide cross-platform interfaces without demaning the
//! consumers to manually handle Java-specific logic for Android. To learn about the strategy to
//! find [`JNI_GetCreatedJavaVMs()`] used by `jvm-getter`, please refer to the documentation of
//! [`find_jni_get_created_java_vms()`]. For compatibility, [`find_jni_get_created_java_vms()`] is
//! also available on Desktop platforms, including Windows, macOS, and Linux.
//!
//! [`JNI_GetCreatedJavaVMs()`]: https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/invocation.html#JNI_GetCreatedJavaVMs
use ;
/// The function pointer type of `JNI_GetCreatedJavaVMs()`.
pub type JNI_GetCreatedJavaVMs =
unsafe extern "system" fn ;
/// Finds the current process's [JNI_GetCreatedJavaVMs]. For compatibility, this function is
/// also available on Desktop platforms other than Android, including Windows, macOS, and Linux.
///
/// # Strategy
///
/// This function finds the address where the Android Runtime is loaded, parses `libart.so` using
/// [goblin], finds the location of [JNI_GetCreatedJavaVMs] in `libart.so`, and computes its
/// location in the memory by adding an offset to the address of `libart.so`.
///
/// On API level 24 or higher, `dlopen`ing private API results in an runtime error. Thus, we locate
/// `libart.so` by iterating over the loaded shared object list of the current process using
/// `dl_iterate_phdr`.
///
/// Since `dlsym` is also prohibited for private APIs, using [goblin] is necessary.
///
/// # Safety
///
/// This function depends on implementation details of Android, not its public APIs. Use at your
/// own risk.
pub unsafe