#[cfg(feature = "loadjvm")]
pub mod test {
use jni_simple::*;
use std::ptr::null_mut;
use std::sync::Mutex;
static MUTEX: Mutex<()> = Mutex::new(());
unsafe fn get_env() -> JNIEnv {
if !is_jvm_loaded() {
load_jvm_from_java_home().expect("failed to load jvm");
}
let thr = JNI_GetCreatedJavaVMs().expect("failed to get jvm");
if thr.is_empty() {
let args: Vec<String> = vec![];
let (_, env) = JNI_CreateJavaVM_with_string_args(JNI_VERSION_1_8, &args)
.expect("failed to create jvm");
return env;
}
let jvm = thr.first().unwrap().clone();
let env = jvm.GetEnv(JNI_VERSION_1_8);
let env = env.unwrap_or_else(|c| {
if c != JNI_EDETACHED {
panic!("JVM ERROR {}", c);
}
jvm.AttachCurrentThread_str(JNI_VERSION_1_8, None, null_mut())
.expect("failed to attach thread")
});
env
}
unsafe fn get_test_class() -> jclass {
let env = get_env();
let class_loaded = env.FindClass_str("FieldTests");
if !class_loaded.is_null() {
let class_global = env.NewGlobalRef(class_loaded);
env.DeleteLocalRef(class_loaded);
return class_global;
}
env.ExceptionClear(); let class_blob = include_bytes!("../java_testcode/FieldTests.class");
let class_loaded = env.DefineClass_str("FieldTests", null_mut(), class_blob);
if class_loaded.is_null() {
env.ExceptionDescribe();
env.FatalError_str("failed to load class");
}
let class_global = env.NewGlobalRef(class_loaded);
env.DeleteLocalRef(class_loaded);
class_global
}
unsafe fn get_test_obj() -> jobject {
let env = get_env();
let tc = get_test_class();
let local_obj = env.GetStaticFieldID_str(tc, "staticInstance", "LFieldTests;");
let test_obj = env.GetStaticObjectField(tc, local_obj);
test_obj
}
unsafe fn reset_it() {
let env = get_env();
let class = get_test_class();
let reset = env.GetStaticMethodID_str(class, "reset", "()V");
env.CallStaticVoidMethod0(class, reset);
env.DeleteGlobalRef(class);
}
unsafe fn add_it() {
let env = get_env();
let class = get_test_class();
let reset = env.GetStaticMethodID_str(class, "add", "()V");
env.CallStaticVoidMethod0(class, reset);
env.DeleteGlobalRef(class);
}
unsafe fn new_global_obj() -> jobject {
let env = get_env();
let class = env.FindClass_str("java/lang/Object");
let meth = env.GetMethodID_str(class, "<init>", "()V");
let obj = env.NewObjectA(class, meth, null_mut());
let gref = env.NewGlobalRef(obj);
env.DeleteLocalRef(obj);
env.DeleteLocalRef(class);
gref
}
#[test]
fn test_bool() {
let _lock = MUTEX.lock().unwrap();
unsafe {
reset_it();
let env = get_env();
let test_class = get_test_class();
let field = env.GetStaticFieldID_str(test_class, "staticBool", "Z");
env.SetStaticBooleanField(test_class, field, true);
assert_eq!(true, env.GetStaticBooleanField(test_class, field));
env.SetStaticBooleanField(test_class, field, false);
assert_eq!(false, env.GetStaticBooleanField(test_class, field));
env.SetStaticBooleanField(test_class, field, false);
assert_eq!(false, env.GetStaticBooleanField(test_class, field));
env.SetStaticBooleanField(test_class, field, true);
env.SetStaticBooleanField(test_class, field, true);
assert_eq!(true, env.GetStaticBooleanField(test_class, field));
add_it();
assert_eq!(false, env.GetStaticBooleanField(test_class, field));
let test_obj = get_test_obj();
let field = env.GetFieldID_str(test_class, "dynBool", "Z");
env.SetBooleanField(test_obj, field, true);
assert_eq!(true, env.GetBooleanField(test_obj, field));
env.SetBooleanField(test_obj, field, false);
assert_eq!(false, env.GetBooleanField(test_obj, field));
env.SetBooleanField(test_obj, field, false);
assert_eq!(false, env.GetBooleanField(test_obj, field));
env.SetBooleanField(test_obj, field, true);
env.SetBooleanField(test_obj, field, true);
assert_eq!(true, env.GetBooleanField(test_obj, field));
add_it();
assert_eq!(false, env.GetBooleanField(test_obj, field));
env.DeleteLocalRef(test_obj);
env.DeleteGlobalRef(test_class);
}
}
#[test]
fn test_byte() {
let _lock = MUTEX.lock().unwrap();
unsafe {
reset_it();
let env = get_env();
let test_class = get_test_class();
let field = env.GetStaticFieldID_str(test_class, "staticByte", "B");
env.SetStaticByteField(test_class, field, 1);
assert_eq!(1, env.GetStaticByteField(test_class, field));
env.SetStaticByteField(test_class, field, 1);
assert_eq!(1, env.GetStaticByteField(test_class, field));
env.SetStaticByteField(test_class, field, 2);
assert_eq!(2, env.GetStaticByteField(test_class, field));
env.SetStaticByteField(test_class, field, 11);
env.SetStaticByteField(test_class, field, 11);
assert_eq!(11, env.GetStaticByteField(test_class, field));
add_it();
assert_eq!(12, env.GetStaticByteField(test_class, field));
let test_obj = get_test_obj();
let field = env.GetFieldID_str(test_class, "dynByte", "B");
env.SetByteField(test_obj, field, 1);
assert_eq!(1, env.GetByteField(test_obj, field));
env.SetByteField(test_obj, field, 1);
assert_eq!(1, env.GetByteField(test_obj, field));
env.SetByteField(test_obj, field, 2);
assert_eq!(2, env.GetByteField(test_obj, field));
env.SetByteField(test_obj, field, 11);
env.SetByteField(test_obj, field, 11);
assert_eq!(11, env.GetByteField(test_obj, field));
add_it();
assert_eq!(12, env.GetByteField(test_obj, field));
env.DeleteLocalRef(test_obj);
env.DeleteGlobalRef(test_class);
}
}
#[test]
fn test_short() {
let _lock = MUTEX.lock().unwrap();
unsafe {
reset_it();
let env = get_env();
let test_class = get_test_class();
let field = env.GetStaticFieldID_str(test_class, "staticShort", "S");
env.SetStaticShortField(test_class, field, 1);
assert_eq!(1, env.GetStaticShortField(test_class, field));
env.SetStaticShortField(test_class, field, 1);
assert_eq!(1, env.GetStaticShortField(test_class, field));
env.SetStaticShortField(test_class, field, 2);
assert_eq!(2, env.GetStaticShortField(test_class, field));
env.SetStaticShortField(test_class, field, 11);
env.SetStaticShortField(test_class, field, 11);
assert_eq!(11, env.GetStaticShortField(test_class, field));
add_it();
assert_eq!(12, env.GetStaticShortField(test_class, field));
let test_obj = get_test_obj();
let field = env.GetFieldID_str(test_class, "dynShort", "S");
env.SetShortField(test_obj, field, 1);
assert_eq!(1, env.GetShortField(test_obj, field));
env.SetShortField(test_obj, field, 1);
assert_eq!(1, env.GetShortField(test_obj, field));
env.SetShortField(test_obj, field, 2);
assert_eq!(2, env.GetShortField(test_obj, field));
env.SetShortField(test_obj, field, 11);
env.SetShortField(test_obj, field, 11);
assert_eq!(11, env.GetShortField(test_obj, field));
add_it();
assert_eq!(12, env.GetShortField(test_obj, field));
env.DeleteLocalRef(test_obj);
env.DeleteGlobalRef(test_class);
}
}
#[test]
fn test_char() {
let _lock = MUTEX.lock().unwrap();
unsafe {
reset_it();
let env = get_env();
let test_class = get_test_class();
let field = env.GetStaticFieldID_str(test_class, "staticChar", "C");
env.SetStaticCharField(test_class, field, 1);
assert_eq!(1, env.GetStaticCharField(test_class, field));
env.SetStaticCharField(test_class, field, 1);
assert_eq!(1, env.GetStaticCharField(test_class, field));
env.SetStaticCharField(test_class, field, 2);
assert_eq!(2, env.GetStaticCharField(test_class, field));
env.SetStaticCharField(test_class, field, 11);
env.SetStaticCharField(test_class, field, 11);
assert_eq!(11, env.GetStaticCharField(test_class, field));
add_it();
assert_eq!(12, env.GetStaticCharField(test_class, field));
let test_obj = get_test_obj();
let field = env.GetFieldID_str(test_class, "dynChar", "C");
env.SetCharField(test_obj, field, 1);
assert_eq!(1, env.GetCharField(test_obj, field));
env.SetCharField(test_obj, field, 1);
assert_eq!(1, env.GetCharField(test_obj, field));
env.SetCharField(test_obj, field, 2);
assert_eq!(2, env.GetCharField(test_obj, field));
env.SetCharField(test_obj, field, 11);
env.SetCharField(test_obj, field, 11);
assert_eq!(11, env.GetCharField(test_obj, field));
add_it();
assert_eq!(12, env.GetCharField(test_obj, field));
env.DeleteLocalRef(test_obj);
env.DeleteGlobalRef(test_class);
}
}
#[test]
fn test_int() {
let _lock = MUTEX.lock().unwrap();
unsafe {
reset_it();
let env = get_env();
let test_class = get_test_class();
let field = env.GetStaticFieldID_str(test_class, "staticInt", "I");
env.SetStaticIntField(test_class, field, 1);
assert_eq!(1, env.GetStaticIntField(test_class, field));
env.SetStaticIntField(test_class, field, 1);
assert_eq!(1, env.GetStaticIntField(test_class, field));
env.SetStaticIntField(test_class, field, 2);
assert_eq!(2, env.GetStaticIntField(test_class, field));
env.SetStaticIntField(test_class, field, 11);
env.SetStaticIntField(test_class, field, 11);
assert_eq!(11, env.GetStaticIntField(test_class, field));
add_it();
assert_eq!(12, env.GetStaticIntField(test_class, field));
let test_obj = get_test_obj();
let field = env.GetFieldID_str(test_class, "dynInt", "I");
env.SetIntField(test_obj, field, 1);
assert_eq!(1, env.GetIntField(test_obj, field));
env.SetIntField(test_obj, field, 1);
assert_eq!(1, env.GetIntField(test_obj, field));
env.SetIntField(test_obj, field, 2);
assert_eq!(2, env.GetIntField(test_obj, field));
env.SetIntField(test_obj, field, 11);
env.SetIntField(test_obj, field, 11);
assert_eq!(11, env.GetIntField(test_obj, field));
add_it();
assert_eq!(12, env.GetIntField(test_obj, field));
env.DeleteLocalRef(test_obj);
env.DeleteGlobalRef(test_class);
}
}
#[test]
fn test_long() {
let _lock = MUTEX.lock().unwrap();
unsafe {
reset_it();
let env = get_env();
let test_class = get_test_class();
let field = env.GetStaticFieldID_str(test_class, "staticLong", "J");
env.SetStaticLongField(test_class, field, 1);
assert_eq!(1, env.GetStaticLongField(test_class, field));
env.SetStaticLongField(test_class, field, 1);
assert_eq!(1, env.GetStaticLongField(test_class, field));
env.SetStaticLongField(test_class, field, 2);
assert_eq!(2, env.GetStaticLongField(test_class, field));
env.SetStaticLongField(test_class, field, 11);
env.SetStaticLongField(test_class, field, 11);
assert_eq!(11, env.GetStaticLongField(test_class, field));
add_it();
assert_eq!(12, env.GetStaticLongField(test_class, field));
let test_obj = get_test_obj();
let field = env.GetFieldID_str(test_class, "dynLong", "J");
env.SetLongField(test_obj, field, 1);
assert_eq!(1, env.GetLongField(test_obj, field));
env.SetLongField(test_obj, field, 1);
assert_eq!(1, env.GetLongField(test_obj, field));
env.SetLongField(test_obj, field, 2);
assert_eq!(2, env.GetLongField(test_obj, field));
env.SetLongField(test_obj, field, 11);
env.SetLongField(test_obj, field, 11);
assert_eq!(11, env.GetLongField(test_obj, field));
add_it();
assert_eq!(12, env.GetLongField(test_obj, field));
env.DeleteLocalRef(test_obj);
env.DeleteGlobalRef(test_class);
}
}
#[test]
fn test_float() {
let _lock = MUTEX.lock().unwrap();
unsafe {
reset_it();
let env = get_env();
let test_class = get_test_class();
let field = env.GetStaticFieldID_str(test_class, "staticFloat", "F");
env.SetStaticFloatField(test_class, field, 1f32);
assert_eq!(1f32, env.GetStaticFloatField(test_class, field));
env.SetStaticFloatField(test_class, field, 1f32);
assert_eq!(1f32, env.GetStaticFloatField(test_class, field));
env.SetStaticFloatField(test_class, field, 2f32);
assert_eq!(2f32, env.GetStaticFloatField(test_class, field));
env.SetStaticFloatField(test_class, field, 11f32);
env.SetStaticFloatField(test_class, field, 11f32);
assert_eq!(11f32, env.GetStaticFloatField(test_class, field));
add_it();
assert_eq!(12f32, env.GetStaticFloatField(test_class, field));
let test_obj = get_test_obj();
let field = env.GetFieldID_str(test_class, "dynFloat", "F");
env.SetFloatField(test_obj, field, 1f32);
assert_eq!(1f32, env.GetFloatField(test_obj, field));
env.SetFloatField(test_obj, field, 1f32);
assert_eq!(1f32, env.GetFloatField(test_obj, field));
env.SetFloatField(test_obj, field, 2f32);
assert_eq!(2f32, env.GetFloatField(test_obj, field));
env.SetFloatField(test_obj, field, 11f32);
env.SetFloatField(test_obj, field, 11f32);
assert_eq!(11f32, env.GetFloatField(test_obj, field));
add_it();
assert_eq!(12f32, env.GetFloatField(test_obj, field));
env.DeleteLocalRef(test_obj);
env.DeleteGlobalRef(test_class);
}
}
#[test]
fn test_double() {
let _lock = MUTEX.lock().unwrap();
unsafe {
reset_it();
let env = get_env();
let test_class = get_test_class();
let field = env.GetStaticFieldID_str(test_class, "staticDouble", "D");
env.SetStaticDoubleField(test_class, field, 1f64);
assert_eq!(1f64, env.GetStaticDoubleField(test_class, field));
env.SetStaticDoubleField(test_class, field, 1f64);
assert_eq!(1f64, env.GetStaticDoubleField(test_class, field));
env.SetStaticDoubleField(test_class, field, 2f64);
assert_eq!(2f64, env.GetStaticDoubleField(test_class, field));
env.SetStaticDoubleField(test_class, field, 11f64);
env.SetStaticDoubleField(test_class, field, 11f64);
assert_eq!(11f64, env.GetStaticDoubleField(test_class, field));
add_it();
assert_eq!(12f64, env.GetStaticDoubleField(test_class, field));
let test_obj = get_test_obj();
let field = env.GetFieldID_str(test_class, "dynDouble", "D");
env.SetDoubleField(test_obj, field, 1f64);
assert_eq!(1f64, env.GetDoubleField(test_obj, field));
env.SetDoubleField(test_obj, field, 1f64);
assert_eq!(1f64, env.GetDoubleField(test_obj, field));
env.SetDoubleField(test_obj, field, 2f64);
assert_eq!(2f64, env.GetDoubleField(test_obj, field));
env.SetDoubleField(test_obj, field, 11f64);
env.SetDoubleField(test_obj, field, 11f64);
assert_eq!(11f64, env.GetDoubleField(test_obj, field));
add_it();
assert_eq!(12f64, env.GetDoubleField(test_obj, field));
env.DeleteLocalRef(test_obj);
env.DeleteGlobalRef(test_class);
}
}
#[test]
fn test_obj() {
let _lock = MUTEX.lock().unwrap();
unsafe {
reset_it();
let g1 = new_global_obj();
let g2 = new_global_obj();
let env = get_env();
let test_class = get_test_class();
let field = env.GetStaticFieldID_str(test_class, "staticObject", "Ljava/lang/Object;");
env.SetStaticObjectField(test_class, field, g1);
assert!(env.IsSameObject(g1, env.GetStaticObjectField(test_class, field)));
env.SetStaticObjectField(test_class, field, g1);
assert!(env.IsSameObject(g1, env.GetStaticObjectField(test_class, field)));
env.SetStaticObjectField(test_class, field, null_mut());
assert!(env.IsSameObject(null_mut(), env.GetStaticObjectField(test_class, field)));
env.SetStaticObjectField(test_class, field, g2);
env.SetStaticObjectField(test_class, field, g2);
assert!(env.IsSameObject(g2, env.GetStaticObjectField(test_class, field)));
let test_obj = get_test_obj();
let field = env.GetFieldID_str(test_class, "dynObject", "Ljava/lang/Object;");
env.SetObjectField(test_obj, field, g1);
assert!(env.IsSameObject(g1, env.GetObjectField(test_obj, field)));
env.SetObjectField(test_obj, field, g1);
assert!(env.IsSameObject(g1, env.GetObjectField(test_obj, field)));
env.SetObjectField(test_obj, field, null_mut());
assert!(env.IsSameObject(null_mut(), env.GetObjectField(test_obj, field)));
env.SetObjectField(test_obj, field, g2);
env.SetObjectField(test_obj, field, g2);
assert!(env.IsSameObject(g2, env.GetObjectField(test_obj, field)));
env.DeleteLocalRef(test_obj);
env.DeleteGlobalRef(test_class);
env.DeleteGlobalRef(g1);
env.DeleteGlobalRef(g2);
}
}
#[test]
fn test_reflect() {
let _lock = MUTEX.lock().unwrap();
unsafe {
let env = get_env();
let test_class = get_test_class();
let field_static = env.GetStaticFieldID_str(test_class, "staticObject", "Ljava/lang/Object;");
assert!(!field_static.is_null());
let field_dyn = env.GetFieldID_str(test_class, "dynObject", "Ljava/lang/Object;");
assert!(!field_dyn.is_null());
let reflect_static = env.ToReflectedField(test_class, field_static, true);
assert!(!reflect_static.is_null());
let reflect_dyn = env.ToReflectedField(test_class, field_dyn, false);
assert!(!reflect_dyn.is_null());
let de_static = env.FromReflectedField(reflect_static);
let de_dyn = env.FromReflectedField(reflect_dyn);
let g1 = new_global_obj();
let g2 = new_global_obj();
env.SetStaticObjectField(test_class, de_static, g1);
assert!(env.IsSameObject(g1, env.GetStaticObjectField(test_class, de_static)));
env.SetStaticObjectField(test_class, de_static, g1);
assert!(env.IsSameObject(g1, env.GetStaticObjectField(test_class, de_static)));
env.SetStaticObjectField(test_class, de_static, null_mut());
assert!(env.IsSameObject(null_mut(), env.GetStaticObjectField(test_class, de_static)));
env.SetStaticObjectField(test_class, de_static, g2);
env.SetStaticObjectField(test_class, de_static, g2);
assert!(env.IsSameObject(g2, env.GetStaticObjectField(test_class, de_static)));
let test_obj = get_test_obj();
env.SetObjectField(test_obj, de_dyn, g1);
assert!(env.IsSameObject(g1, env.GetObjectField(test_obj, de_dyn)));
env.SetObjectField(test_obj, de_dyn, g1);
assert!(env.IsSameObject(g1, env.GetObjectField(test_obj, de_dyn)));
env.SetObjectField(test_obj, de_dyn, null_mut());
assert!(env.IsSameObject(null_mut(), env.GetObjectField(test_obj, de_dyn)));
env.SetObjectField(test_obj, de_dyn, g2);
env.SetObjectField(test_obj, de_dyn, g2);
assert!(env.IsSameObject(g2, env.GetObjectField(test_obj, de_dyn)));
env.DeleteLocalRef(reflect_static);
env.DeleteLocalRef(reflect_dyn);
env.DeleteLocalRef(test_obj);
env.DeleteGlobalRef(test_class);
env.DeleteGlobalRef(g1);
env.DeleteGlobalRef(g2);
}
}
}