{"record":{"id":"9aa457a5e76e0eb3","repo":"risingwavelabs/risingwave","slug":"input-object-is-not-a-java-string-and-can-t-be-con","errorCode":null,"errorMessage":"Input object is not a java string and can't be converted!","messagePattern":"Input object is not a java string and can't be converted!","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/jni_core/src/jvm_runtime.rs","lineNumber":270,"sourceCode":"            let message = call_method!(env, exception, {String getMessage()})?;\n            let message = jobj_to_str(&mut env, message)?;\n            return Err(anyhow::anyhow!(\"Caught Java Exception: {}\", message));\n        }\n        Ok(false) => {\n            // No exception, do nothing\n        }\n        Err(e) => {\n            tracing::warn!(error = %e.as_report(), \"Failed to check exception\");\n        }\n    }\n\n    ret\n}\n\n/// A helper method to convert an java object to rust string.\npub fn jobj_to_str(env: &mut JNIEnv<'_>, obj: JObject<'_>) -> anyhow::Result<String> {\n    if !env.is_instance_of(&obj, \"java/lang/String\")? {\n        bail!(\"Input object is not a java string and can't be converted!\")\n    }\n    let jstr = JString::from(obj);\n    let java_str = env.get_string(&jstr)?;\n    Ok(java_str.to_str()?.to_owned())\n}\n\n/// Dumps the JVM stack traces.\n///\n/// # Returns\n///\n/// - `Ok(None)` if JVM is not initialized.\n/// - `Ok(Some(String))` if JVM is initialized and stack traces are dumped.\n/// - `Err` if failed to dump stack traces.\npub fn dump_jvm_stack_traces() -> anyhow::Result<Option<String>> {\n    match Jvm::get() {\n        None => Ok(None),\n        Some(jvm) => execute_with_jni_env(jvm, |env| {\n            let result = call_static_method!(","sourceCodeStart":252,"sourceCodeEnd":288,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/jni_core/src/jvm_runtime.rs#L252-L288","documentation":"jobj_to_str converts a returned Java object to a Rust String but first verifies the object is an instance of java/lang/String. If it is not, it bails with this error instead of attempting an unsafe cast. It guards JNI calls whose Java methods are expected to return strings (namespace/table names, exception messages).","triggerScenarios":"A Java method invoked via list_namespaces, list_tables, create_table, load_table, update_table, or execute_with_jni_env returns a non-String object where a String was expected, e.g. a patched/incorrect Debezium-Iceberg jar returning a different type.","commonSituations":"Mismatched jar versions where the Java method signature changed and now returns an array or custom type, a null object being returned by the Java side, using an outdated or hand-patched connector jar.","solutions":["Ensure the connector/iceberg jars in CONNECTOR_LIBS_PATH match the versions RisingWave expects (risingwave-source-cdc first on classpath).","Inspect the Java method being called and confirm its return type is String.","Check whether the returned object is null/None from the Java side and handle it before conversion.","Update or reinstall the connector package to fix signature drift."],"exampleFix":"// before (java side)\npublic Object listTables() { return tablesList; } // returns List, not String\n// after (java side)\npublic String listTables() { return serialize(tablesList); }","handlingStrategy":"try-catch","validationCode":"// verify expected jar version is on the classpath\nls \"$CONNECTOR_LIBS_PATH\" | grep -q 'risingwave-connector' && echo ok || echo 'connector jars missing or outdated'","typeGuard":null,"tryCatchPattern":"match catalog.list_tables() {\n    Err(e) if e.to_string().contains(\"not a java string\") => {\n        // suspect jar version mismatch or null return; refresh jars and retry\n    }\n    other => other?,\n}","preventionTips":["Keep connector jars pinned to the versions RisingWave documents; update them together.","Never substitute hand-patched jars without checking return-type signatures.","Add a startup assertion that the Java methods used return String where expected.","Handle null returns on the Java side so JNI never receives a non-String."],"tags":["jvm","jni","java","type-mismatch"],"backgroundTag":"type-mismatch","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}