use jni_sys::{
JavaVM, JavaVMInitArgs, JavaVMOption, JNI_CreateJavaVM, JNI_ERR, JNI_EDETACHED, JNI_EVERSION,
JNI_ENOMEM, JNI_EEXIST, JNI_EINVAL, JNI_FALSE, JNI_OK, JNI_VERSION_1_8, JNIEnv, jboolean, jbyte,
jchar, jint, jdouble, jfloat, jlong, jobject, jshort, jvalue
};
use std::ffi::CString;
use std::ptr;
use std::os::raw::c_void;
#[link(name="jvm")]
extern {
}
pub unsafe fn jvalue_from_jboolean(arg: jboolean) -> jvalue {
jvalue { z: arg }
}
pub unsafe fn jvalue_from_jbyte(arg: jbyte) -> jvalue {
jvalue { b: arg }
}
pub unsafe fn jvalue_from_jchar(arg: jchar) -> jvalue {
jvalue { c: arg }
}
pub unsafe fn jvalue_from_jdouble(arg: jdouble) -> jvalue {
jvalue { d: arg }
}
pub unsafe fn jvalue_from_jint(arg: jint) -> jvalue {
jvalue { i: arg }
}
pub unsafe fn jvalue_from_jfloat(arg: jfloat) -> jvalue {
jvalue { f: arg }
}
pub unsafe fn jvalue_from_jlong(arg: jlong) -> jvalue {
jvalue { j: arg }
}
pub unsafe fn jvalue_from_jobject(arg: jobject) -> jvalue {
jvalue { l: arg }
}
pub unsafe fn jvalue_from_jshort(arg: jshort) -> jvalue {
jvalue { s: arg }
}
unsafe fn jvm_exception_occured(jni_environment: *mut JNIEnv) -> bool {
return !(**jni_environment).ExceptionOccurred.unwrap()(jni_environment).is_null()
}
pub unsafe fn print_and_panic_on_jvm_exception(jni_environment: *mut JNIEnv) {
if jvm_exception_occured(jni_environment) {
(**jni_environment).ExceptionDescribe.unwrap()(jni_environment);
panic!("An exception occurred");
};
}
pub unsafe fn print_jvm_exception(jni_environment: *mut JNIEnv) {
if jvm_exception_occured(jni_environment) {
(**jni_environment).ExceptionDescribe.unwrap()(jni_environment);
};
}
pub struct Jvm {
jvm: *mut JavaVM,
}
impl Jvm {
pub fn jvm(&self) -> *mut JavaVM {
self.jvm
}
pub unsafe fn new(jvm_option_strings: &[&str]) -> Jvm {
let mut jvm_option_cstrings : Vec<CString> = Vec::new();
for jvm_option_string in jvm_option_strings {
jvm_option_cstrings.push(CString::new(*jvm_option_string).unwrap());
}
let mut jvm_options : Vec<JavaVMOption> = Vec::new();
for jvm_option_cstring in &jvm_option_cstrings {
let jvm_option = JavaVMOption {
optionString: jvm_option_cstring.as_ptr() as *mut i8,
extraInfo: ptr::null_mut() as *mut c_void
};
jvm_options.push(jvm_option);
}
let mut jvm_arguments = JavaVMInitArgs {
version: JNI_VERSION_1_8,
options: jvm_options.as_mut_ptr(),
nOptions: jvm_options.len() as i32,
ignoreUnrecognized: JNI_FALSE
};
let mut jvm: *mut JavaVM = ptr::null_mut();
let mut jni_environment : *mut JNIEnv = ptr::null_mut();
let result = JNI_CreateJavaVM(
&mut jvm,
(&mut jni_environment as *mut *mut JNIEnv) as *mut *mut c_void,
(&mut jvm_arguments as *mut JavaVMInitArgs) as *mut c_void
);
if result != JNI_OK {
let error_message = match result {
JNI_EDETACHED => "thread detached from JVM",
JNI_EEXIST => "JVM exists already",
JNI_EINVAL => "invalid arguments",
JNI_ENOMEM => "not enough memory",
JNI_ERR => "unknown error",
JNI_EVERSION => "JNI version error",
_ => "unknown JNI error value",
};
panic!("`JNI_CreateJavaVM()` signaled an error: {}", error_message);
}
Jvm { jvm }
}
}
impl Drop for Jvm {
fn drop(&mut self) {
}
}