1 use std::sync::{Arc, Once};
2 
3 use jni::{
4     errors::Result, objects::JValue, sys::jint, AttachGuard, InitArgsBuilder, JNIEnv, JNIVersion,
5     JavaVM,
6 };
7 
8 mod example_proxy;
9 pub use self::example_proxy::AtomicIntegerProxy;
10 
jvm() -> &'static Arc<JavaVM>11 pub fn jvm() -> &'static Arc<JavaVM> {
12     static mut JVM: Option<Arc<JavaVM>> = None;
13     static INIT: Once = Once::new();
14 
15     INIT.call_once(|| {
16         let jvm_args = InitArgsBuilder::new()
17             .version(JNIVersion::V8)
18             .option("-Xcheck:jni")
19             .build()
20             .unwrap_or_else(|e| panic!("{:#?}", e));
21 
22         let jvm = JavaVM::new(jvm_args).unwrap_or_else(|e| panic!("{:#?}", e));
23 
24         unsafe {
25             JVM = Some(Arc::new(jvm));
26         }
27     });
28 
29     unsafe { JVM.as_ref().unwrap() }
30 }
31 
32 #[allow(dead_code)]
call_java_abs(env: &mut JNIEnv, value: i32) -> i3233 pub fn call_java_abs(env: &mut JNIEnv, value: i32) -> i32 {
34     env.call_static_method(
35         "java/lang/Math",
36         "abs",
37         "(I)I",
38         &[JValue::from(value as jint)],
39     )
40     .unwrap()
41     .i()
42     .unwrap()
43 }
44 
45 #[allow(dead_code)]
attach_current_thread() -> AttachGuard<'static>46 pub fn attach_current_thread() -> AttachGuard<'static> {
47     jvm()
48         .attach_current_thread()
49         .expect("failed to attach jvm thread")
50 }
51 
52 #[allow(dead_code)]
attach_current_thread_as_daemon() -> JNIEnv<'static>53 pub fn attach_current_thread_as_daemon() -> JNIEnv<'static> {
54     jvm()
55         .attach_current_thread_as_daemon()
56         .expect("failed to attach jvm daemon thread")
57 }
58 
59 #[allow(dead_code)]
attach_current_thread_permanently() -> JNIEnv<'static>60 pub fn attach_current_thread_permanently() -> JNIEnv<'static> {
61     jvm()
62         .attach_current_thread_permanently()
63         .expect("failed to attach jvm thread permanently")
64 }
65 
66 #[allow(dead_code)]
detach_current_thread()67 pub unsafe fn detach_current_thread() {
68     jvm().detach_current_thread()
69 }
70 
print_exception(env: &JNIEnv)71 pub fn print_exception(env: &JNIEnv) {
72     let exception_occurred = env.exception_check().unwrap_or_else(|e| panic!("{:?}", e));
73     if exception_occurred {
74         env.exception_describe()
75             .unwrap_or_else(|e| panic!("{:?}", e));
76     }
77 }
78 
79 #[allow(dead_code)]
unwrap<T>(res: Result<T>, env: &JNIEnv) -> T80 pub fn unwrap<T>(res: Result<T>, env: &JNIEnv) -> T {
81     res.unwrap_or_else(|e| {
82         print_exception(env);
83         panic!("{:#?}", e);
84     })
85 }
86