Skip to content

Commit

Permalink
feat(java-binding): generate jni method signature with macro (#12487)
Browse files Browse the repository at this point in the history
  • Loading branch information
wenym1 authored Sep 26, 2023
1 parent 42290e4 commit b75ff79
Show file tree
Hide file tree
Showing 8 changed files with 412 additions and 180 deletions.
3 changes: 3 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src/java_binding/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ ignored = ["workspace-hack"]
normal = ["workspace-hack"]

[dependencies]
jni = "0.21.1"
prost = "0.11"
risingwave_common = { workspace = true }
risingwave_jni_core = { workspace = true }
Expand Down
4 changes: 2 additions & 2 deletions src/java_binding/make-java-binding.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ script = '''
#!/usr/bin/env bash
set -ex
cd java
mvn install --no-transfer-progress --pl java-binding-integration-test --am -DskipTests=true
mvn install --no-transfer-progress --pl java-binding-integration-test --am -DskipTests=true -Dmaven.javadoc.skip=true
mvn dependency:copy-dependencies --no-transfer-progress --pl java-binding-integration-test
'''

Expand Down Expand Up @@ -109,7 +109,7 @@ RISINGWAVE_ROOT=$(git rev-parse --show-toplevel)
cd ${RISINGWAVE_ROOT}/java
mvn install --pl java-binding-benchmark --am -DskipTests=true
mvn install --pl java-binding-benchmark --am -DskipTests=true -Dmaven.javadoc.skip=true
mvn dependency:copy-dependencies --pl java-binding-benchmark
Expand Down
16 changes: 15 additions & 1 deletion src/java_binding/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,18 @@
// See the License for the specific language governing permissions and
// limitations under the License.

pub use risingwave_jni_core::*;
#![feature(result_option_inspect)]

use std::ffi::c_void;

use jni::sys::{jint, JNI_VERSION_1_2};
use jni::JavaVM;
use risingwave_jni_core::register_native_method_for_jvm;

#[no_mangle]
#[allow(non_snake_case)]
pub extern "system" fn JNI_OnLoad(jvm: JavaVM, _reserved: *mut c_void) -> jint {
let _ = register_native_method_for_jvm(&jvm)
.inspect_err(|_e| eprintln!("unable to register native method"));
JNI_VERSION_1_2
}
2 changes: 2 additions & 0 deletions src/jni_core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@ normal = ["workspace-hack"]

[dependencies]
bytes = "1"
cfg-or-panic = "0.2"
futures = { version = "0.3", default-features = false, features = ["alloc"] }
itertools = "0.11"
jni = "0.21.1"
paste = "1"
prost = "0.11"
risingwave_common = { workspace = true }
risingwave_hummock_sdk = { workspace = true }
Expand Down
201 changes: 26 additions & 175 deletions src/jni_core/src/jvm_runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,12 +91,12 @@ pub static JVM: LazyLock<Result<JavaVM, RwError>> = LazyLock::new(|| {

tracing::info!("initialize JVM successfully");

register_native_method_for_jvm(&jvm);
register_native_method_for_jvm(&jvm).unwrap();

Ok(jvm)
});

fn register_native_method_for_jvm(jvm: &JavaVM) {
pub fn register_native_method_for_jvm(jvm: &JavaVM) -> Result<(), jni::errors::Error> {
let mut env = jvm
.attach_current_thread()
.inspect_err(|e| tracing::error!("jvm attach thread error: {:?}", e))
Expand All @@ -106,179 +106,30 @@ fn register_native_method_for_jvm(jvm: &JavaVM) {
.find_class("com/risingwave/java/binding/Binding")
.inspect_err(|e| tracing::error!("jvm find class error: {:?}", e))
.unwrap();
env.register_native_methods(
binding_class,
&[
NativeMethod {
name: JNIString::from("vnodeCount"),
sig: JNIString::from("()I"),
fn_ptr: crate::Java_com_risingwave_java_binding_Binding_vnodeCount as *mut c_void,
},
#[cfg(not(madsim))]
NativeMethod {
name: JNIString::from("hummockIteratorNew"),
sig: JNIString::from("([B)J"),
fn_ptr: crate::Java_com_risingwave_java_binding_Binding_hummockIteratorNew
as *mut c_void,
},
#[cfg(not(madsim))]
NativeMethod {
name: JNIString::from("hummockIteratorNext"),
sig: JNIString::from("(J)J"),
fn_ptr: crate::Java_com_risingwave_java_binding_Binding_hummockIteratorNext
as *mut c_void,
},
NativeMethod {
name: JNIString::from("hummockIteratorClose"),
sig: JNIString::from("(J)V"),
fn_ptr: crate::Java_com_risingwave_java_binding_Binding_hummockIteratorClose
as *mut c_void,
},
NativeMethod {
name: JNIString::from("rowGetKey"),
sig: JNIString::from("(J)[B"),
fn_ptr: crate::Java_com_risingwave_java_binding_Binding_rowGetKey as *mut c_void,
},
NativeMethod {
name: JNIString::from("rowGetOp"),
sig: JNIString::from("(J)I"),
fn_ptr: crate::Java_com_risingwave_java_binding_Binding_rowGetOp as *mut c_void,
},
NativeMethod {
name: JNIString::from("rowIsNull"),
sig: JNIString::from("(JI)Z"),
fn_ptr: crate::Java_com_risingwave_java_binding_Binding_rowIsNull as *mut c_void,
},
NativeMethod {
name: JNIString::from("rowGetInt16Value"),
sig: JNIString::from("(JI)S"),
fn_ptr: crate::Java_com_risingwave_java_binding_Binding_rowGetInt16Value
as *mut c_void,
},
NativeMethod {
name: JNIString::from("rowGetInt32Value"),
sig: JNIString::from("(JI)I"),
fn_ptr: crate::Java_com_risingwave_java_binding_Binding_rowGetInt32Value
as *mut c_void,
},
NativeMethod {
name: JNIString::from("rowGetInt64Value"),
sig: JNIString::from("(JI)J"),
fn_ptr: crate::Java_com_risingwave_java_binding_Binding_rowGetInt64Value
as *mut c_void,
},
NativeMethod {
name: JNIString::from("rowGetFloatValue"),
sig: JNIString::from("(JI)F"),
fn_ptr: crate::Java_com_risingwave_java_binding_Binding_rowGetFloatValue
as *mut c_void,
},
NativeMethod {
name: JNIString::from("rowGetDoubleValue"),
sig: JNIString::from("(JI)D"),
fn_ptr: crate::Java_com_risingwave_java_binding_Binding_rowGetDoubleValue
as *mut c_void,
},
NativeMethod {
name: JNIString::from("rowGetBooleanValue"),
sig: JNIString::from("(JI)Z"),
fn_ptr: crate::Java_com_risingwave_java_binding_Binding_rowGetBooleanValue
as *mut c_void,
},
NativeMethod {
name: JNIString::from("rowGetStringValue"),
sig: JNIString::from("(JI)Ljava/lang/String;"),
fn_ptr: crate::Java_com_risingwave_java_binding_Binding_rowGetStringValue
as *mut c_void,
},
NativeMethod {
name: JNIString::from("rowGetTimestampValue"),
sig: JNIString::from("(JI)Ljava/sql/Timestamp;"),
fn_ptr: crate::Java_com_risingwave_java_binding_Binding_rowGetTimestampValue
as *mut c_void,
},
NativeMethod {
name: JNIString::from("rowGetDecimalValue"),
sig: JNIString::from("(JI)Ljava/math/BigDecimal;"),
fn_ptr: crate::Java_com_risingwave_java_binding_Binding_rowGetDecimalValue
as *mut c_void,
},
NativeMethod {
name: JNIString::from("rowGetTimeValue"),
sig: JNIString::from("(JI)Ljava/sql/Time;"),
fn_ptr: crate::Java_com_risingwave_java_binding_Binding_rowGetTimeValue
as *mut c_void,
},
NativeMethod {
name: JNIString::from("rowGetDateValue"),
sig: JNIString::from("(JI)Ljava/sql/Date;"),
fn_ptr: crate::Java_com_risingwave_java_binding_Binding_rowGetDateValue
as *mut c_void,
},
NativeMethod {
name: JNIString::from("rowGetIntervalValue"),
sig: JNIString::from("(JI)Ljava/lang/String;"),
fn_ptr: crate::Java_com_risingwave_java_binding_Binding_rowGetIntervalValue
as *mut c_void,
},
NativeMethod {
name: JNIString::from("rowGetJsonbValue"),
sig: JNIString::from("(JI)Ljava/lang/String;"),
fn_ptr: crate::Java_com_risingwave_java_binding_Binding_rowGetJsonbValue
as *mut c_void,
},
NativeMethod {
name: JNIString::from("rowGetByteaValue"),
sig: JNIString::from("(JI)[B"),
fn_ptr: crate::Java_com_risingwave_java_binding_Binding_rowGetByteaValue
as *mut c_void,
},
NativeMethod {
name: JNIString::from("rowGetArrayValue"),
sig: JNIString::from("(JILjava/lang/Class;)Ljava/lang/Object;"),
fn_ptr: crate::Java_com_risingwave_java_binding_Binding_rowGetArrayValue
as *mut c_void,
},
NativeMethod {
name: JNIString::from("rowClose"),
sig: JNIString::from("(J)V"),
fn_ptr: crate::Java_com_risingwave_java_binding_Binding_rowClose as *mut c_void,
},
NativeMethod {
name: JNIString::from("streamChunkIteratorNew"),
sig: JNIString::from("([B)J"),
fn_ptr: crate::Java_com_risingwave_java_binding_Binding_streamChunkIteratorNew
as *mut c_void,
},
NativeMethod {
name: JNIString::from("streamChunkIteratorNext"),
sig: JNIString::from("(J)J"),
fn_ptr: crate::Java_com_risingwave_java_binding_Binding_streamChunkIteratorNext
as *mut c_void,
},
NativeMethod {
name: JNIString::from("streamChunkIteratorClose"),
sig: JNIString::from("(J)V"),
fn_ptr: crate::Java_com_risingwave_java_binding_Binding_streamChunkIteratorClose
as *mut c_void,
},
NativeMethod {
name: JNIString::from("streamChunkIteratorFromPretty"),
sig: JNIString::from("(Ljava/lang/String;)J"),
fn_ptr:
crate::Java_com_risingwave_java_binding_Binding_streamChunkIteratorFromPretty
as *mut c_void,
},
NativeMethod {
name: JNIString::from("sendCdcSourceMsgToChannel"),
sig: JNIString::from("(J[B)Z"),
fn_ptr: crate::Java_com_risingwave_java_binding_Binding_sendCdcSourceMsgToChannel
as *mut c_void,
},
],
)
.inspect_err(|e| tracing::error!("jvm register native methods error: {:?}", e))
.unwrap();
use crate::*;
macro_rules! gen_native_method_array {
() => {{
$crate::for_all_native_methods! {gen_native_method_array}
}};
({$({ $func_name:ident, {$($ret:tt)+}, {$($args:tt)*} }),*}) => {
[
$(
{
let fn_ptr = paste::paste! {[<Java_com_risingwave_java_binding_Binding_ $func_name> ]} as *mut c_void;
let sig = $crate::gen_jni_sig! { $($ret)+ ($($args)*)};
NativeMethod {
name: JNIString::from(stringify! {$func_name}),
sig: JNIString::from(sig),
fn_ptr,
}
},
)*
]
}
}
env.register_native_methods(binding_class, &gen_native_method_array!())
.inspect_err(|e| tracing::error!("jvm register native methods error: {:?}", e))?;

tracing::info!("register native methods for jvm successfully");
Ok(())
}
7 changes: 5 additions & 2 deletions src/jni_core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

pub mod hummock_iterator;
pub mod jvm_runtime;
mod macros;
pub mod stream_chunk_iterator;

use std::backtrace::Backtrace;
Expand All @@ -28,6 +29,7 @@ use std::ops::{Deref, DerefMut};
use std::slice::from_raw_parts;
use std::sync::{Arc, LazyLock, OnceLock};

use cfg_or_panic::cfg_or_panic;
use hummock_iterator::{HummockJavaBindingIterator, KeyedRow};
use jni::objects::{
AutoElements, GlobalRef, JByteArray, JClass, JMethodID, JObject, JStaticMethodID, JString,
Expand All @@ -51,6 +53,7 @@ use thiserror::Error;
use tokio::runtime::Runtime;
use tokio::sync::mpsc::Sender;

pub use crate::jvm_runtime::register_native_method_for_jvm;
use crate::stream_chunk_iterator::{StreamChunkIterator, StreamChunkRow};
pub type GetEventStreamJniSender = Sender<GetEventStreamResponse>;

Expand Down Expand Up @@ -296,7 +299,7 @@ pub extern "system" fn Java_com_risingwave_java_binding_Binding_vnodeCount(
VirtualNode::COUNT as jint
}

#[cfg(not(madsim))]
#[cfg_or_panic(not(madsim))]
#[no_mangle]
pub extern "system" fn Java_com_risingwave_java_binding_Binding_hummockIteratorNew<'a>(
env: EnvParam<'a>,
Expand All @@ -309,7 +312,7 @@ pub extern "system" fn Java_com_risingwave_java_binding_Binding_hummockIteratorN
})
}

#[cfg(not(madsim))]
#[cfg_or_panic(not(madsim))]
#[no_mangle]
pub extern "system" fn Java_com_risingwave_java_binding_Binding_hummockIteratorNext<'a>(
env: EnvParam<'a>,
Expand Down
Loading

0 comments on commit b75ff79

Please sign in to comment.