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