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