{"record":{"id":"5cf7524c2eee4484","repo":"risingwavelabs/risingwave","slug":"caught-java-exception","errorCode":null,"errorMessage":"Caught Java Exception: {}","messagePattern":"Caught Java Exception: (.+?)","errorType":"exception","errorClass":"anyhow","httpStatus":null,"severity":"error","filePath":"src/jni_core/src/jvm_runtime.rs","lineNumber":254,"sourceCode":"        &system_class_loader\n    )?;\n\n    let ret = f(&mut env);\n\n    match env.exception_check() {\n        Ok(true) => {\n            let exception = env.exception_occurred().inspect_err(|e| {\n                tracing::warn!(error = %e.as_report(), \"Failed to get jvm exception\");\n            })?;\n            env.exception_describe().inspect_err(|e| {\n                tracing::warn!(error = %e.as_report(), \"Failed to describe jvm exception\");\n            })?;\n            env.exception_clear().inspect_err(|e| {\n                tracing::warn!(error = %e.as_report(), \"Exception occurred but failed to clear\");\n            })?;\n            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);","sourceCodeStart":236,"sourceCodeEnd":272,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/jni_core/src/jvm_runtime.rs#L236-L272","documentation":"After invoking a Java method through JNI (via the execute_with_jni_env wrapper used by all Iceberg REST catalog operations), the code checks ExceptionCheck. If a Java exception is pending, its message is extracted via getMessage() and returned as a Rust error prefixed with `Caught Java Exception:`. This surfaces underlying Java-side failures (network to catalog, auth, schema issues) into Rust error handling.","triggerScenarios":"Any of list_namespaces, create_namespace, namespace_exists, list_tables, create_table, load_table raising a Java exception on the JNI side — e.g. Iceberg REST catalog returning HTTP 4xx/5xx, missing classpath entries causing ClassNotFoundException, or invalid arguments from Rust.","commonSituations":"Iceberg REST catalog unreachable or misconfigured (wrong URI/credentials), missing Debezium/iceberg jars on the classpath, OAuth token invalid on the catalog side, table/namespace already exists.","solutions":["Read the Java message after `Caught Java Exception:` — it names the actual Java-side cause.","Verify the Iceberg catalog URI, credentials, and warehouse config are correct.","Ensure all required jars are present in CONNECTOR_LIBS_PATH (classpath complete).","Fix the specific catalog error (auth, existing object, network) indicated by the message.","Re-run with Java-side logging enabled for a full stack trace."],"exampleFix":"// before\nLOAD TABLE iceberg_t FROM iceberg WITH (catalog.uri='http://wrong-host:9000/catalog')\n// after\nLOAD TABLE iceberg_t FROM iceberg WITH (catalog.uri='http://catalog-host:9000/catalog', catalog.credential='...')","handlingStrategy":"try-catch","validationCode":"// preflight: catalog reachable\nconst res = await fetch(catalogUri); if (!res.ok) throw new Error(`iceberg catalog ${catalogUri} returned ${res.status}`);","typeGuard":null,"tryCatchPattern":"match catalog.list_namespaces() {\n    Err(e) if e.to_string().starts_with(\"Caught Java Exception:\") => {\n        let java_msg = e.to_string();\n        // inspect java_msg for cause: auth, not-found, already-exists, network\n    }\n    other => other?,\n}","preventionTips":["Verify Iceberg catalog URI, credentials, and warehouse settings before creating sources.","Keep CONNECTOR_LIBS_PATH jars at supported versions, with risingwave-source-cdc first.","Preflight connectivity to the catalog host/port.","Enable Java-side stack-trace logging to map messages back to causes."],"tags":["jvm","jni","java","iceberg"],"backgroundTag":"java-exception-in-jni","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}