jni/wrapper/
errors.rs

1#![allow(missing_docs)]
2
3use thiserror::Error;
4
5use crate::sys;
6use crate::wrapper::signature::TypeSignature;
7
8pub type Result<T> = std::result::Result<T, Error>;
9
10#[derive(Debug, Error)]
11pub enum Error {
12    #[error("Invalid JValue type cast: {0}. Actual type: {1}")]
13    WrongJValueType(&'static str, &'static str),
14    #[error("Invalid constructor return type (must be void)")]
15    InvalidCtorReturn,
16    #[error("Invalid number or type of arguments passed to java method: {0}")]
17    InvalidArgList(TypeSignature),
18    #[error("Method not found: {name} {sig}")]
19    MethodNotFound { name: String, sig: String },
20    #[error("Field not found: {name} {sig}")]
21    FieldNotFound { name: String, sig: String },
22    #[error("Java exception was thrown")]
23    JavaException,
24    #[error("JNIEnv null method pointer for {0}")]
25    JNIEnvMethodNotFound(&'static str),
26    #[error("Null pointer in {0}")]
27    NullPtr(&'static str),
28    #[error("Null pointer deref in {0}")]
29    NullDeref(&'static str),
30    #[error("Mutex already locked")]
31    TryLock,
32    #[error("JavaVM null method pointer for {0}")]
33    JavaVMMethodNotFound(&'static str),
34    #[error("Field already set: {0}")]
35    FieldAlreadySet(String),
36    #[error("Throw failed with error code {0}")]
37    ThrowFailed(i32),
38    #[error("Parse failed for input: {1}")]
39    ParseFailed(#[source] combine::error::StringStreamError, String),
40    #[error("JNI call failed")]
41    JniCall(#[source] JniError),
42}
43
44#[derive(Debug, Error)]
45pub enum JniError {
46    #[error("Unknown error")]
47    Unknown,
48    #[error("Current thread is not attached to the Java VM")]
49    ThreadDetached,
50    #[error("JNI version error")]
51    WrongVersion,
52    #[error("Not enough memory")]
53    NoMemory,
54    #[error("VM already created")]
55    AlreadyCreated,
56    #[error("Invalid arguments")]
57    InvalidArguments,
58    #[error("Error code {0}")]
59    Other(sys::jint),
60}
61
62impl<T> From<::std::sync::TryLockError<T>> for Error {
63    fn from(_: ::std::sync::TryLockError<T>) -> Self {
64        Error::TryLock
65    }
66}
67
68pub fn jni_error_code_to_result(code: sys::jint) -> Result<()> {
69    match code {
70        sys::JNI_OK => Ok(()),
71        sys::JNI_ERR => Err(JniError::Unknown),
72        sys::JNI_EDETACHED => Err(JniError::ThreadDetached),
73        sys::JNI_EVERSION => Err(JniError::WrongVersion),
74        sys::JNI_ENOMEM => Err(JniError::NoMemory),
75        sys::JNI_EEXIST => Err(JniError::AlreadyCreated),
76        sys::JNI_EINVAL => Err(JniError::InvalidArguments),
77        _ => Err(JniError::Other(code)),
78    }
79    .map_err(Error::JniCall)
80}
81
82pub struct Exception {
83    pub class: String,
84    pub msg: String,
85}
86
87pub trait ToException {
88    fn to_exception(&self) -> Exception;
89}
90
91/// An error that occurred while starting the JVM using the JNI Invocation API.
92///
93/// This only exists if the "invocation" feature is enabled.
94#[cfg(feature = "invocation")]
95#[derive(Debug, Error)]
96#[non_exhaustive]
97pub enum StartJvmError {
98    /// An attempt was made to find a JVM using [java-locator], but it failed.
99    ///
100    /// If this happens, give an explicit location to [`JavaVM::with_libjvm`] or set the
101    /// `JAVA_HOME` environment variable.
102    ///
103    /// [java-locator]: https://docs.rs/java-locator/
104    /// [`JavaVM::with_libjvm`]: crate::JavaVM::with_libjvm
105    #[error("Couldn't automatically discover the Java VM's location (try setting the JAVA_HOME environment variable): {0}")]
106    NotFound(
107        #[from]
108        #[source]
109        java_locator::errors::JavaLocatorError,
110    ),
111
112    /// An error occurred in trying to load the JVM shared library.
113    ///
114    /// On Windows, if this happens it may be necessary to add your `$JAVA_HOME/bin` directory
115    /// to the DLL search path by adding it to the `PATH` environment variable.
116    #[error("Couldn't load the Java VM shared library ({0}): {1}")]
117    LoadError(String, #[source] libloading::Error),
118
119    /// The JNI function `JNI_CreateJavaVM` returned an error.
120    #[error("{0}")]
121    Create(
122        #[from]
123        #[source]
124        Error,
125    ),
126}
127
128#[cfg(feature = "invocation")]
129pub type StartJvmResult<T> = std::result::Result<T, StartJvmError>;