mirror of
https://github.com/k2-fsa/sherpa-onnx.git
synced 2026-11-10 21:11:03 +08:00
jni: convert C++ exceptions in recognizer/punctuation constructors to Java exceptions (#3988)
An exception escaping a JNI boundary calls std::terminate and aborts the process. In production we observed an Ort::Exception raised while loading a corrupt model file inside OfflineRecognizer::newFromFile take down the whole app, uncatchable from Kotlin. Wrap every model-loading JNI constructor (offline/online recognizer, offline/online punctuation, both the file and the asset variants) in a try/catch that converts the C++ exception into a Java exception via ThrowNew, following the existing pattern in jni/wave-reader.cc. The helper RethrowCxxExceptionAsJava lives in jni/common.h. Fixes #3987
This commit is contained in:
1 parent
9db1af1871
commit
6e7ea3e409
5 files changed
+88
-13
No files matched your search
@@ -5,8 +5,10 @@
|
||||
#ifndef SHERPA_ONNX_JNI_COMMON_H_
|
||||
#define SHERPA_ONNX_JNI_COMMON_H_
|
||||
|
||||
#include <exception> // NOLINT
|
||||
#include <string>
|
||||
|
||||
#include "sherpa-onnx/csrc/macros.h"
|
||||
#include "sherpa-onnx/csrc/text-utils.h"
|
||||
|
||||
#if __ANDROID_API__ >= 9
|
||||
@@ -223,4 +225,35 @@ namespace sherpa_onnx {
|
||||
void PrependAdspLibraryPath(const std::string &new_path);
|
||||
}
|
||||
|
||||
|
||||
// Convert a C++ exception caught in a JNI function into a Java exception, so
|
||||
// callers on the Kotlin/Java side can catch it. Without this, an exception
|
||||
// escaping a JNI boundary calls std::terminate and aborts the process (e.g. an
|
||||
// Ort::Exception raised while loading a corrupt model file).
|
||||
inline void RethrowCxxExceptionAsJava(JNIEnv *env, const std::exception &e,
|
||||
const char *context) {
|
||||
SHERPA_ONNX_LOGE("%s: %s", context, e.what());
|
||||
// JNI string functions expect modified UTF-8; an arbitrary what() buffer is
|
||||
// not guaranteed to be valid, and ThrowNew with malformed input is
|
||||
// undefined at the boundary. Fall back to the (ASCII, literal) context when
|
||||
// the message is not printable ASCII, so the Java side always gets a valid
|
||||
// string; the full message is preserved in the log line above.
|
||||
const char *msg = e.what();
|
||||
bool printable = msg[0] != '\0';
|
||||
for (const char *p = msg; *p; ++p) {
|
||||
unsigned char c = static_cast<unsigned char>(*p);
|
||||
if (c < 0x20 || c > 0x7e) {
|
||||
printable = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
jclass exception_class = env->FindClass("java/lang/Exception");
|
||||
if (exception_class == nullptr) {
|
||||
// FindClass itself failed; nothing more we can do here.
|
||||
return;
|
||||
}
|
||||
env->ThrowNew(exception_class, printable ? msg : context);
|
||||
env->DeleteLocalRef(exception_class);
|
||||
}
|
||||
|
||||
#endif // SHERPA_ONNX_JNI_COMMON_H_
|
||||
@@ -63,11 +63,17 @@ Java_com_k2fsa_sherpa_onnx_OfflinePunctuation_newFromAsset(
|
||||
|
||||
SHERPA_ONNX_LOGE("config:\n%s", config.ToString().c_str());
|
||||
|
||||
auto model = new sherpa_onnx::OfflinePunctuation(
|
||||
sherpa_onnx::OfflinePunctuation *model = nullptr;
|
||||
try {
|
||||
model = new sherpa_onnx::OfflinePunctuation(
|
||||
#if __ANDROID_API__ >= 9
|
||||
mgr,
|
||||
mgr,
|
||||
#endif
|
||||
config);
|
||||
config);
|
||||
} catch (const std::exception &e) {
|
||||
RethrowCxxExceptionAsJava(env, e, "Failed to create OfflinePunctuation");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (jlong)model;
|
||||
}
|
||||
@@ -92,7 +98,13 @@ Java_com_k2fsa_sherpa_onnx_OfflinePunctuation_newFromFile(JNIEnv *env,
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto model = new sherpa_onnx::OfflinePunctuation(config);
|
||||
sherpa_onnx::OfflinePunctuation *model = nullptr;
|
||||
try {
|
||||
model = new sherpa_onnx::OfflinePunctuation(config);
|
||||
} catch (const std::exception &e) {
|
||||
RethrowCxxExceptionAsJava(env, e, "Failed to create OfflinePunctuation");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (jlong)model;
|
||||
}
|
||||
|
||||
@@ -546,7 +546,13 @@ Java_com_k2fsa_sherpa_onnx_OfflineRecognizer_newFromFile(JNIEnv *env,
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto model = new sherpa_onnx::OfflineRecognizer(config);
|
||||
sherpa_onnx::OfflineRecognizer *model = nullptr;
|
||||
try {
|
||||
model = new sherpa_onnx::OfflineRecognizer(config);
|
||||
} catch (const std::exception &e) {
|
||||
RethrowCxxExceptionAsJava(env, e, "Failed to create OfflineRecognizer");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (jlong)model;
|
||||
}
|
||||
|
||||
@@ -68,11 +68,17 @@ Java_com_k2fsa_sherpa_onnx_OnlinePunctuation_newFromAsset(JNIEnv *env,
|
||||
|
||||
SHERPA_ONNX_LOGE("config:\n%s", config.ToString().c_str());
|
||||
|
||||
auto model = new sherpa_onnx::OnlinePunctuation(
|
||||
sherpa_onnx::OnlinePunctuation *model = nullptr;
|
||||
try {
|
||||
model = new sherpa_onnx::OnlinePunctuation(
|
||||
#if __ANDROID_API__ >= 9
|
||||
mgr,
|
||||
mgr,
|
||||
#endif
|
||||
config);
|
||||
config);
|
||||
} catch (const std::exception &e) {
|
||||
RethrowCxxExceptionAsJava(env, e, "Failed to create OnlinePunctuation");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (jlong)model;
|
||||
}
|
||||
@@ -97,7 +103,13 @@ Java_com_k2fsa_sherpa_onnx_OnlinePunctuation_newFromFile(JNIEnv *env,
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto model = new sherpa_onnx::OnlinePunctuation(config);
|
||||
sherpa_onnx::OnlinePunctuation *model = nullptr;
|
||||
try {
|
||||
model = new sherpa_onnx::OnlinePunctuation(config);
|
||||
} catch (const std::exception &e) {
|
||||
RethrowCxxExceptionAsJava(env, e, "Failed to create OnlinePunctuation");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (jlong)model;
|
||||
}
|
||||
|
||||
@@ -273,11 +273,17 @@ Java_com_k2fsa_sherpa_onnx_OnlineRecognizer_newFromAsset(JNIEnv *env,
|
||||
#endif
|
||||
}
|
||||
|
||||
auto recognizer = new sherpa_onnx::OnlineRecognizer(
|
||||
sherpa_onnx::OnlineRecognizer *recognizer = nullptr;
|
||||
try {
|
||||
recognizer = new sherpa_onnx::OnlineRecognizer(
|
||||
#if __ANDROID_API__ >= 9
|
||||
mgr,
|
||||
mgr,
|
||||
#endif
|
||||
config);
|
||||
config);
|
||||
} catch (const std::exception &e) {
|
||||
RethrowCxxExceptionAsJava(env, e, "Failed to create OnlineRecognizer");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (jlong)recognizer;
|
||||
}
|
||||
@@ -309,7 +315,13 @@ JNIEXPORT jlong JNICALL Java_com_k2fsa_sherpa_onnx_OnlineRecognizer_newFromFile(
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto recognizer = new sherpa_onnx::OnlineRecognizer(config);
|
||||
sherpa_onnx::OnlineRecognizer *recognizer = nullptr;
|
||||
try {
|
||||
recognizer = new sherpa_onnx::OnlineRecognizer(config);
|
||||
} catch (const std::exception &e) {
|
||||
RethrowCxxExceptionAsJava(env, e, "Failed to create OnlineRecognizer");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (jlong)recognizer;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user