Xuanwo commented on code in PR #2112:
URL:
https://github.com/apache/incubator-opendal/pull/2112#discussion_r1177536946
##########
bindings/java/src/lib.rs:
##########
@@ -15,20 +15,97 @@
// specific language governing permissions and limitations
// under the License.
+use std::cell::RefCell;
use std::collections::HashMap;
+use std::ffi::c_void;
use std::str::FromStr;
+use std::sync::Arc;
-use jni::objects::JClass;
use jni::objects::JMap;
use jni::objects::JObject;
use jni::objects::JString;
-use jni::sys::jboolean;
-use jni::sys::jlong;
-use jni::JNIEnv;
+use jni::objects::{JClass, JValue};
+use jni::sys::{jboolean, jint};
+use jni::sys::{jlong, JNI_VERSION_1_8};
+use jni::{JNIEnv, JavaVM};
+use once_cell::sync::OnceCell;
+use tokio::runtime::{Builder, Runtime};
+
use opendal::BlockingOperator;
use opendal::Operator;
use opendal::Scheme;
+static mut RUNTIME: OnceCell<Runtime> = OnceCell::new();
+
+thread_local! {
+ static JAVA_VM: RefCell<Option<Arc<JavaVM>>> = RefCell::new(None);
+ static JENV: RefCell<Option<*mut jni::sys::JNIEnv>> = RefCell::new(None);
+}
+
+fn get_system_property(env: &mut JNIEnv, key: &str) -> Result<String,
jni::errors::Error> {
+ let system_class = env.find_class("java/lang/System")?;
+ let key = env.new_string(key)?;
+ let value = env.call_static_method(
+ system_class,
+ "getProperty",
+ "(Ljava/lang/String;)Ljava/lang/String;",
+ &[JValue::Object(key.as_ref())],
+ )?;
+
+ Ok(env
+ .get_string(JString::from(value.l().unwrap()).as_ref())?
+ .into())
+}
+
+/// # Safety
+///
+/// This function could be only called by java vm when load this lib.
+#[no_mangle]
+pub unsafe extern "system" fn JNI_OnLoad(vm: JavaVM, _: *mut c_void) -> jint {
+ let mut env = vm.get_env().unwrap();
+ let thread_count = match get_system_property(&mut env,
"opendal.thread.count") {
Review Comment:
I prefer to remove this to keep simple. We can make this configurable in the
future.
##########
bindings/java/src/lib.rs:
##########
@@ -15,20 +15,97 @@
// specific language governing permissions and limitations
// under the License.
+use std::cell::RefCell;
use std::collections::HashMap;
+use std::ffi::c_void;
use std::str::FromStr;
+use std::sync::Arc;
-use jni::objects::JClass;
use jni::objects::JMap;
use jni::objects::JObject;
use jni::objects::JString;
-use jni::sys::jboolean;
-use jni::sys::jlong;
-use jni::JNIEnv;
+use jni::objects::{JClass, JValue};
+use jni::sys::{jboolean, jint};
+use jni::sys::{jlong, JNI_VERSION_1_8};
+use jni::{JNIEnv, JavaVM};
+use once_cell::sync::OnceCell;
+use tokio::runtime::{Builder, Runtime};
+
use opendal::BlockingOperator;
use opendal::Operator;
use opendal::Scheme;
+static mut RUNTIME: OnceCell<Runtime> = OnceCell::new();
+
+thread_local! {
+ static JAVA_VM: RefCell<Option<Arc<JavaVM>>> = RefCell::new(None);
+ static JENV: RefCell<Option<*mut jni::sys::JNIEnv>> = RefCell::new(None);
+}
+
+fn get_system_property(env: &mut JNIEnv, key: &str) -> Result<String,
jni::errors::Error> {
+ let system_class = env.find_class("java/lang/System")?;
+ let key = env.new_string(key)?;
+ let value = env.call_static_method(
+ system_class,
+ "getProperty",
+ "(Ljava/lang/String;)Ljava/lang/String;",
+ &[JValue::Object(key.as_ref())],
+ )?;
+
+ Ok(env
+ .get_string(JString::from(value.l().unwrap()).as_ref())?
+ .into())
+}
+
+/// # Safety
+///
+/// This function could be only called by java vm when load this lib.
+#[no_mangle]
+pub unsafe extern "system" fn JNI_OnLoad(vm: JavaVM, _: *mut c_void) -> jint {
+ let mut env = vm.get_env().unwrap();
+ let thread_count = match get_system_property(&mut env,
"opendal.thread.count") {
+ Ok(count) => count.parse().unwrap_or(num_cpus::get()),
+ Err(_) => num_cpus::get(),
+ };
+
+ let java_vm = Arc::new(vm);
+ let runtime = Builder::new_multi_thread()
+ .worker_threads(thread_count)
+ .on_thread_start(move || {
+ JENV.with(|cell| {
+ let env = java_vm.attach_current_thread_as_daemon().unwrap();
+ *cell.borrow_mut() = Some(env.get_raw());
+ });
+ JAVA_VM.with(|cell| {
+ *cell.borrow_mut() = Some(java_vm.clone());
+ });
+ })
+ .on_thread_stop(move || {
+ JENV.with(|cell| {
+ *cell.borrow_mut() = None;
+ });
+ JAVA_VM.with(|cell| unsafe {
+ if let Some(vm) = cell.borrow_mut().take() {
+ vm.detach_current_thread();
+ }
+ });
+ })
+ .build()
+ .unwrap();
+ RUNTIME.set(runtime).unwrap();
+ JNI_VERSION_1_8
Review Comment:
Do we need to align with latest LTS like java 17? Or at least, java 11?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]