1 #![allow(missing_docs)]
2 
3 use thiserror::Error;
4 
5 use crate::sys;
6 use crate::wrapper::signature::TypeSignature;
7 
8 pub type Result<T> = std::result::Result<T, Error>;
9 
10 #[derive(Debug, Error)]
11 pub 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)]
45 pub 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 
62 impl<T> From<::std::sync::TryLockError<T>> for Error {
from(_: ::std::sync::TryLockError<T>) -> Self63     fn from(_: ::std::sync::TryLockError<T>) -> Self {
64         Error::TryLock
65     }
66 }
67 
jni_error_code_to_result(code: sys::jint) -> Result<()>68 pub 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 
82 pub struct Exception {
83     pub class: String,
84     pub msg: String,
85 }
86 
87 pub trait ToException {
to_exception(&self) -> Exception88     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]
97 pub 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")]
129 pub type StartJvmResult<T> = std::result::Result<T, StartJvmError>;
130