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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#[derive(Copy, Clone)]
#[doc(hidden)]
pub struct JMethodIDHack {
pub jmethodid: jni::sys::jmethodID,
}
unsafe impl Send for JMethodIDHack {
}
unsafe impl Sync for JMethodIDHack {
}
#[macro_export]
macro_rules! get_java_class {
($env:expr, $class_name:expr) => {{
use $crate::{
reimport::{
jni::objects::JClass,
parking_lot::{
const_rwlock,
RwLock,
},
},
JniError,
UniGlobalRef as UGR,
};
static CACHE: RwLock<Option<UGR<JClass<'static>>>> = const_rwlock(None);
let read_lock = CACHE.read();
let result = match read_lock.as_ref() {
Some(bc) => Ok(bc.clone()),
None => {
std::mem::drop(read_lock);
match $env.find_class($class_name) {
Err(e) => Err(JniError::JniError(e)),
Ok(class) => {
let class: JClass<'static> = class.into_inner().into();
match UGR::try_new($env, class) {
Err(e) => Err(e),
Ok(class) => {
*CACHE.write() = Some(class.clone());
Ok(class)
},
}
},
}
},
};
result
}};
}
#[macro_export]
macro_rules! get_java_method {
($env:expr, $class:expr, $method_name:expr, $method_signature:expr) => {{
use $crate::{
macroses::JMethodIDHack,
reimport::{
jni::objects::JMethodID,
parking_lot::{
const_rwlock,
RwLock,
},
},
};
static CACHE: RwLock<Option<JMethodIDHack>> = const_rwlock(None);
let method = CACHE.read();
let jmethodid = match method.as_ref() {
Some(method) => method.jmethodid,
None => {
std::mem::drop(method);
let maybe_method =
$env.get_method_id($class, $method_name, $method_signature);
let method = match maybe_method {
Ok(method) => method,
Err(e) => {
log::error!("get_method err:{:?}", e);
let _ =
$env.get_method_id($class, $method_name, $method_signature);
panic!("get_method failed");
},
};
let method = JMethodIDHack {
jmethodid: method.into_inner(),
};
*CACHE.write() = Some(method);
method.jmethodid
},
};
JMethodID::from(jmethodid)
}};
}