From b6a7aaf9e0f3bbb38e2d559231a189f05936c799 Mon Sep 17 00:00:00 2001 From: G-XD Date: Wed, 27 Sep 2023 01:18:48 +0800 Subject: [PATCH 1/3] =?UTF-8?q?fix(binding/java):=20decode=20Java=E2=80=99?= =?UTF-8?q?s=20modified=20UTF-8=20format?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bindings/java/src/blocking_operator.rs | 20 +++++++++--------- bindings/java/src/operator.rs | 21 ++++++++++--------- .../test/behavior/AbstractBehaviorTest.java | 15 +++++++++++++ 3 files changed, 36 insertions(+), 20 deletions(-) diff --git a/bindings/java/src/blocking_operator.rs b/bindings/java/src/blocking_operator.rs index 55a645a4763b..1bd31f64d935 100644 --- a/bindings/java/src/blocking_operator.rs +++ b/bindings/java/src/blocking_operator.rs @@ -55,8 +55,8 @@ pub unsafe extern "system" fn Java_org_apache_opendal_BlockingOperator_read( } fn intern_read(env: &mut JNIEnv, op: &mut BlockingOperator, path: JString) -> Result { - let path = env.get_string(&path)?; - let content = op.read(path.to_str()?)?; + let path: String = env.get_string(&path)?.into(); + let content = op.read(&path)?; let result = env.byte_array_from_slice(content.as_slice())?; Ok(result.into_raw()) } @@ -83,9 +83,9 @@ fn intern_write( path: JString, content: JByteArray, ) -> Result<()> { - let path = env.get_string(&path)?; + let path: String = env.get_string(&path)?.into(); let content = env.convert_byte_array(content)?; - Ok(op.write(path.to_str()?, content)?) + Ok(op.write(&path, content)?) } /// # Safety @@ -105,8 +105,8 @@ pub unsafe extern "system" fn Java_org_apache_opendal_BlockingOperator_stat( } fn intern_stat(env: &mut JNIEnv, op: &mut BlockingOperator, path: JString) -> Result { - let path = env.get_string(&path)?; - let metadata = op.stat(path.to_str()?)?; + let path: String = env.get_string(&path)?.into(); + let metadata = op.stat(&path)?; Ok(Box::into_raw(Box::new(metadata)) as jlong) } @@ -126,8 +126,8 @@ pub unsafe extern "system" fn Java_org_apache_opendal_BlockingOperator_delete( } fn intern_delete(env: &mut JNIEnv, op: &mut BlockingOperator, path: JString) -> Result<()> { - let path = env.get_string(&path)?; - Ok(op.delete(path.to_str()?)?) + let path: String = env.get_string(&path)?.into(); + Ok(op.delete(&path)?) } /// # Safety @@ -146,6 +146,6 @@ pub unsafe extern "system" fn Java_org_apache_opendal_BlockingOperator_createDir } fn intern_create_dir(env: &mut JNIEnv, op: &mut BlockingOperator, path: JString) -> Result<()> { - let path = env.get_string(&path)?; - Ok(op.create_dir(path.to_str()?)?) + let path: String = env.get_string(&path)?.into(); + Ok(op.create_dir(&path)?) } diff --git a/bindings/java/src/operator.rs b/bindings/java/src/operator.rs index 8f0c1549ec33..c207ab52950a 100644 --- a/bindings/java/src/operator.rs +++ b/bindings/java/src/operator.rs @@ -52,7 +52,8 @@ pub extern "system" fn Java_org_apache_opendal_Operator_constructor( } fn intern_constructor(env: &mut JNIEnv, scheme: JString, map: JObject) -> Result { - let scheme = Scheme::from_str(env.get_string(&scheme)?.to_str()?)?; + let schema: String = env.get_string(&scheme)?.into(); + let scheme = Scheme::from_str(&schema)?; let map = jmap_to_hashmap(env, &map)?; let mut op = Operator::via_map(scheme, map)?; if !op.info().full_capability().blocking { @@ -100,7 +101,7 @@ fn intern_write( let op = unsafe { &mut *op }; let id = request_id(env)?; - let path = env.get_string(&path)?.to_str()?.to_string(); + let path = env.get_string(&path)?.into(); let content = env.convert_byte_array(content)?; unsafe { get_global_runtime() }.spawn(async move { @@ -141,7 +142,7 @@ fn intern_append( let op = unsafe { &mut *op }; let id = request_id(env)?; - let path = env.get_string(&path)?.to_str()?.to_string(); + let path = env.get_string(&path)?.into(); let content = env.convert_byte_array(content)?; unsafe { get_global_runtime() }.spawn(async move { @@ -176,7 +177,7 @@ fn intern_stat(env: &mut JNIEnv, op: *mut Operator, path: JString) -> Result Result Result Resu let op = unsafe { &mut *op }; let id = request_id(env)?; - let path = env.get_string(&path)?.to_str()?.to_string(); + let path = env.get_string(&path)?.into(); unsafe { get_global_runtime() }.spawn(async move { let result = do_create_dir(op, path).await; @@ -356,7 +357,7 @@ fn intern_presign_read( let op = unsafe { &mut *op }; let id = request_id(env)?; - let path = env.get_string(&path)?.to_str()?.to_string(); + let path = env.get_string(&path)?.into(); let expire = Duration::from_nanos(expire as u64); unsafe { get_global_runtime() }.spawn(async move { @@ -403,7 +404,7 @@ fn intern_presign_write( let op = unsafe { &mut *op }; let id = request_id(env)?; - let path = env.get_string(&path)?.to_str()?.to_string(); + let path = env.get_string(&path)?.into(); let expire = Duration::from_nanos(expire as u64); unsafe { get_global_runtime() }.spawn(async move { @@ -450,7 +451,7 @@ fn intern_presign_stat( let op = unsafe { &mut *op }; let id = request_id(env)?; - let path = env.get_string(&path)?.to_str()?.to_string(); + let path = env.get_string(&path)?.into(); let expire = Duration::from_nanos(expire as u64); unsafe { get_global_runtime() }.spawn(async move { diff --git a/bindings/java/src/test/java/org/apache/opendal/test/behavior/AbstractBehaviorTest.java b/bindings/java/src/test/java/org/apache/opendal/test/behavior/AbstractBehaviorTest.java index 9df34a604bfb..df594fddb7d7 100644 --- a/bindings/java/src/test/java/org/apache/opendal/test/behavior/AbstractBehaviorTest.java +++ b/bindings/java/src/test/java/org/apache/opendal/test/behavior/AbstractBehaviorTest.java @@ -134,6 +134,21 @@ public void testStatFile() { } operator.delete(path).join(); } + + /** + * Write file with non ascii name should succeed. + */ + @Test + public void testWriteFileWithNonAsciiName() { + final String path = "βŒπŸ˜±δΈ­ζ–‡.test"; + final byte[] content = generateBytes(); + operator.write(path, content).join(); + try (final Metadata meta = operator.stat(path).join()) { + assertThat(meta.isFile()).isTrue(); + assertThat(meta.getContentLength()).isEqualTo(content.length); + } + operator.delete(path).join(); + } } @TestInstance(TestInstance.Lifecycle.PER_CLASS) From 4de1bb8c3652004dbf4d8d8deafe92da88471685 Mon Sep 17 00:00:00 2001 From: G-XD Date: Wed, 27 Sep 2023 11:25:35 +0800 Subject: [PATCH 2/3] refactor(binding/java): refactor repeat conversion of jstring to string --- bindings/java/src/blocking_operator.rs | 11 ++++++----- bindings/java/src/lib.rs | 5 +++++ bindings/java/src/operator.rs | 22 +++++++++++----------- 3 files changed, 22 insertions(+), 16 deletions(-) diff --git a/bindings/java/src/blocking_operator.rs b/bindings/java/src/blocking_operator.rs index 1bd31f64d935..c7fb4a076e8d 100644 --- a/bindings/java/src/blocking_operator.rs +++ b/bindings/java/src/blocking_operator.rs @@ -24,6 +24,7 @@ use jni::JNIEnv; use opendal::BlockingOperator; +use crate::jstring_to_string; use crate::Result; /// # Safety @@ -55,7 +56,7 @@ pub unsafe extern "system" fn Java_org_apache_opendal_BlockingOperator_read( } fn intern_read(env: &mut JNIEnv, op: &mut BlockingOperator, path: JString) -> Result { - let path: String = env.get_string(&path)?.into(); + let path = jstring_to_string(env, &path)?; let content = op.read(&path)?; let result = env.byte_array_from_slice(content.as_slice())?; Ok(result.into_raw()) @@ -83,7 +84,7 @@ fn intern_write( path: JString, content: JByteArray, ) -> Result<()> { - let path: String = env.get_string(&path)?.into(); + let path = jstring_to_string(env, &path)?; let content = env.convert_byte_array(content)?; Ok(op.write(&path, content)?) } @@ -105,7 +106,7 @@ pub unsafe extern "system" fn Java_org_apache_opendal_BlockingOperator_stat( } fn intern_stat(env: &mut JNIEnv, op: &mut BlockingOperator, path: JString) -> Result { - let path: String = env.get_string(&path)?.into(); + let path = jstring_to_string(env, &path)?; let metadata = op.stat(&path)?; Ok(Box::into_raw(Box::new(metadata)) as jlong) } @@ -126,7 +127,7 @@ pub unsafe extern "system" fn Java_org_apache_opendal_BlockingOperator_delete( } fn intern_delete(env: &mut JNIEnv, op: &mut BlockingOperator, path: JString) -> Result<()> { - let path: String = env.get_string(&path)?.into(); + let path = jstring_to_string(env, &path)?; Ok(op.delete(&path)?) } @@ -146,6 +147,6 @@ pub unsafe extern "system" fn Java_org_apache_opendal_BlockingOperator_createDir } fn intern_create_dir(env: &mut JNIEnv, op: &mut BlockingOperator, path: JString) -> Result<()> { - let path: String = env.get_string(&path)?.into(); + let path = jstring_to_string(env, &path)?; Ok(op.create_dir(&path)?) } diff --git a/bindings/java/src/lib.rs b/bindings/java/src/lib.rs index e293f1b05505..c2afebd07ab6 100644 --- a/bindings/java/src/lib.rs +++ b/bindings/java/src/lib.rs @@ -221,3 +221,8 @@ fn make_capability<'a>(env: &mut JNIEnv<'a>, cap: Capability) -> Result Result { + let res = unsafe { env.get_string_unchecked(s)? }; + Ok(res.into()) +} diff --git a/bindings/java/src/operator.rs b/bindings/java/src/operator.rs index c207ab52950a..3244ac0adf33 100644 --- a/bindings/java/src/operator.rs +++ b/bindings/java/src/operator.rs @@ -34,6 +34,7 @@ use opendal::Scheme; use crate::get_current_env; use crate::get_global_runtime; use crate::jmap_to_hashmap; +use crate::jstring_to_string; use crate::make_operator_info; use crate::make_presigned_request; use crate::Result; @@ -52,8 +53,7 @@ pub extern "system" fn Java_org_apache_opendal_Operator_constructor( } fn intern_constructor(env: &mut JNIEnv, scheme: JString, map: JObject) -> Result { - let schema: String = env.get_string(&scheme)?.into(); - let scheme = Scheme::from_str(&schema)?; + let scheme = Scheme::from_str(jstring_to_string(env, &scheme)?.as_str())?; let map = jmap_to_hashmap(env, &map)?; let mut op = Operator::via_map(scheme, map)?; if !op.info().full_capability().blocking { @@ -101,7 +101,7 @@ fn intern_write( let op = unsafe { &mut *op }; let id = request_id(env)?; - let path = env.get_string(&path)?.into(); + let path = jstring_to_string(env, &path)?; let content = env.convert_byte_array(content)?; unsafe { get_global_runtime() }.spawn(async move { @@ -142,7 +142,7 @@ fn intern_append( let op = unsafe { &mut *op }; let id = request_id(env)?; - let path = env.get_string(&path)?.into(); + let path = jstring_to_string(env, &path)?; let content = env.convert_byte_array(content)?; unsafe { get_global_runtime() }.spawn(async move { @@ -177,7 +177,7 @@ fn intern_stat(env: &mut JNIEnv, op: *mut Operator, path: JString) -> Result Result Result Resu let op = unsafe { &mut *op }; let id = request_id(env)?; - let path = env.get_string(&path)?.into(); + let path = jstring_to_string(env, &path)?; unsafe { get_global_runtime() }.spawn(async move { let result = do_create_dir(op, path).await; @@ -357,7 +357,7 @@ fn intern_presign_read( let op = unsafe { &mut *op }; let id = request_id(env)?; - let path = env.get_string(&path)?.into(); + let path = jstring_to_string(env, &path)?; let expire = Duration::from_nanos(expire as u64); unsafe { get_global_runtime() }.spawn(async move { @@ -404,7 +404,7 @@ fn intern_presign_write( let op = unsafe { &mut *op }; let id = request_id(env)?; - let path = env.get_string(&path)?.into(); + let path = jstring_to_string(env, &path)?; let expire = Duration::from_nanos(expire as u64); unsafe { get_global_runtime() }.spawn(async move { @@ -451,7 +451,7 @@ fn intern_presign_stat( let op = unsafe { &mut *op }; let id = request_id(env)?; - let path = env.get_string(&path)?.into(); + let path = jstring_to_string(env, &path)?; let expire = Duration::from_nanos(expire as u64); unsafe { get_global_runtime() }.spawn(async move { From 1286601713bea9095f8249e8b5a0b41676837ec5 Mon Sep 17 00:00:00 2001 From: G-XD Date: Wed, 27 Sep 2023 14:13:29 +0800 Subject: [PATCH 3/3] chore(binding/java): add comment --- bindings/java/src/lib.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/bindings/java/src/lib.rs b/bindings/java/src/lib.rs index c2afebd07ab6..d46f6d715076 100644 --- a/bindings/java/src/lib.rs +++ b/bindings/java/src/lib.rs @@ -222,6 +222,10 @@ fn make_capability<'a>(env: &mut JNIEnv<'a>, cap: Capability) -> Result Result { let res = unsafe { env.get_string_unchecked(s)? }; Ok(res.into())