#[repr(transparent)]pub struct Jvm(pub &'static JavaVM);
Expand description
Wrapper for the global JVM instance.
To obtain the instance, use Jvm::get_or_init()
or Jvm::get()
.
Tuple Fields§
§0: &'static JavaVM
Implementations§
Source§impl Jvm
impl Jvm
Sourcepub fn get_or_init() -> Result<Self>
pub fn get_or_init() -> Result<Self>
Get the global singleton JVM instance, initializing it with the registered builder if not already initialized.
Sourcepub fn get() -> Option<Self>
pub fn get() -> Option<Self>
Get the global singleton JVM instance, returning None
if not initialized.
Use Jvm::get_or_init()
if you want to initialize the JVM.
Methods from Deref<Target = JavaVM>§
pub fn get_java_vm_pointer(&self) -> *mut *const JNIInvokeInterface_
pub fn get_java_vm_pointer(&self) -> *mut *const JNIInvokeInterface_
Returns underlying sys::JavaVM
interface.
pub fn attach_current_thread_permanently(&self) -> Result<JNIEnv<'_>, Error>
pub fn attach_current_thread_permanently(&self) -> Result<JNIEnv<'_>, Error>
Attaches the current thread to the JVM. Calling this for a thread that is already attached is a no-op.
The thread will detach itself automatically when it exits.
Attached threads block JVM exit. If it is not desirable — consider using
attach_current_thread_as_daemon
.
pub fn attach_current_thread(&self) -> Result<AttachGuard<'_>, Error>
pub fn attach_current_thread(&self) -> Result<AttachGuard<'_>, Error>
Attaches the current thread to the Java VM. The returned AttachGuard
can be dereferenced to a JNIEnv
and automatically detaches the thread
when dropped. Calling this in a thread that is already attached is a no-op, and
will neither change its daemon status nor prematurely detach it.
Attached threads block JVM exit.
Attaching and detaching a thread is an expensive operation. If you use it frequently
in the same threads, consider either attaching them permanently,
or, if the scope where you need the JNIEnv
is well-defined, keeping the returned guard.
pub unsafe fn detach_current_thread(&self)
pub unsafe fn detach_current_thread(&self)
Explicitly detaches the current thread from the JVM.
Note: This operation is rarely appropriate to use, because the attachment methods ensure that the thread is automatically detached.
Detaching a non-attached thread is a no-op.
To support the use of JavaVM::destroy()
it may be necessary to use this API to
explicitly detach daemon threads before JavaVM::destroy()
is called because
JavaVM::destroy()
does not synchronize and wait for daemon threads.
Any daemon thread that is still “attached” after JavaVM::destroy()
returns would
cause undefined behaviour if it then tries to make any JNI calls or tries
to detach itself.
Normally jni-rs
will automatically detach threads from the JavaVM
by storing
a guard in thread-local-storage that will detach on Drop
but this will cause
undefined behaviour if JavaVM::destroy()
has been called.
Calling this will clear the thread-local-storage guard and detach the thread early to avoid any attempt to automatically detach when the thread exits.
§Safety
Any existing JNIEnv
s and AttachGuard
s created in the calling thread
will be invalidated after this method completes. It is the caller’s responsibility
to ensure that no JNI calls are subsequently performed on these objects.
Failure to do so will result in unspecified errors, possibly, the process crash.
Given some care is exercised, this method can be used to detach permanently attached
threads before they exit (when automatic detachment occurs). However, it is
never appropriate to use it with the scoped attachment (attach_current_thread
).
pub fn attach_current_thread_as_daemon(&self) -> Result<JNIEnv<'_>, Error>
pub fn attach_current_thread_as_daemon(&self) -> Result<JNIEnv<'_>, Error>
Attaches the current thread to the Java VM as a daemon. Calling this in a thread that is already attached is a no-op, and will not change its status to a daemon thread.
The thread will detach itself automatically when it exits.
pub fn threads_attached(&self) -> usize
pub fn threads_attached(&self) -> usize
Returns the current number of threads attached to the JVM.
This method is provided mostly for diagnostic purposes.
pub fn get_env(&self) -> Result<JNIEnv<'_>, Error>
pub fn get_env(&self) -> Result<JNIEnv<'_>, Error>
Get the JNIEnv
associated with the current thread, or
ErrorKind::Detached
if the current thread is not attached to the java VM.
pub unsafe fn destroy(&self) -> Result<(), Error>
pub unsafe fn destroy(&self) -> Result<(), Error>
Unloads the JavaVM and frees all it’s associated resources
Firstly if this thread is not already attached to the JavaVM
then
it will be attached.
This thread will then wait until there are no other non-daemon threads
attached to the JavaVM
before unloading it (including threads spawned
by Java and those that are attached via JNI)
§Safety
IF YOU ARE USING DAEMON THREADS THIS MAY BE DIFFICULT TO USE SAFELY!
§Daemon thread rules
Since the JNI spec makes it clear that DestroyJavaVM
will not wait for
attached deamon threads to exit, this also means that if you do have any
attached daemon threads it is your responsibility to ensure that they
don’t try and use JNI after the JavaVM
is destroyed and you won’t be able
to detach them after the JavaVM
has been destroyed.
This creates a very unsafe hazard in jni-rs
because it normally automatically
ensures that any thread that gets attached will be detached before it exits.
Normally jni-rs
will automatically detach threads from the JavaVM
by storing
a guard in thread-local-storage that will detach on Drop
but this will cause
undefined behaviour if JavaVM::destroy()
has been called before the thread
exits.
To clear this thread-local-storage guard from daemon threads you can call
[JavaVM::detach_current_thread()
] within each daemon thread, before calling
this API.
Calling this will clear the thread-local-storage guard and detach the thread early to avoid any attempt to automatically detach when the thread exits.
§Don’t call from a Java native function
There must be no Java methods on the call stack when JavaVM::destroy()
is called.
§Drop all JNI state, including auto-release types before calling JavaVM::destroy()
There is currently no 'vm
lifetime associated with a JavaVM
that
would allow the borrow checker to enforce that all jni
resources
associated with the JavaVM
have been released.
Since these JNI resources could lead to undefined behaviour through any
use after the JavaVM
has been destroyed then it is your responsibility
to release these resources.
In particular, there are numerous auto-release types in the jni
API
that will automatically make JNI calls within their Drop
implementation. All such types must be dropped before destroy()
is
called to avoid undefined bahaviour.
Here is an non-exhaustive list of auto-release types to consider:
AttachGuard
AutoElements
AutoElementsCritical
AutoLocal
GlobalRef
JavaStr
JMap
WeakRef
§Invalid JavaVM
on return
After destroy()
returns then the JavaVM
will be in an undefined state
and must be dropped (e.g. via std::mem::drop()
) to avoid undefined behaviour.
This method doesn’t take ownership of the JavaVM
before it is
destroyed because the JavaVM
may have been shared (E.g. via an Arc
)
between all the threads that have not yet necessarily exited before this
is called.
So although the JavaVM
won’t necessarily be solely owned by this
thread when destroy()
is first called it will conceptually own the
JavaVM
before destroy()
returns.
Trait Implementations§
Auto Trait Implementations§
impl Freeze for Jvm
impl RefUnwindSafe for Jvm
impl Send for Jvm
impl Sync for Jvm
impl Unpin for Jvm
impl UnwindSafe for Jvm
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<T> Conv for T
impl<T> Conv for T
§impl<T> FmtForward for T
impl<T> FmtForward for T
§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self
to use its Binary
implementation when Debug
-formatted.§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self
to use its Display
implementation when
Debug
-formatted.§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self
to use its LowerExp
implementation when
Debug
-formatted.§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self
to use its LowerHex
implementation when
Debug
-formatted.§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self
to use its Octal
implementation when Debug
-formatted.§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self
to use its Pointer
implementation when
Debug
-formatted.§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self
to use its UpperExp
implementation when
Debug
-formatted.§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self
to use its UpperHex
implementation when
Debug
-formatted.§fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
§impl<T> FutureExt for T
impl<T> FutureExt for T
§fn with_context(self, otel_cx: Context) -> WithContext<Self>
fn with_context(self, otel_cx: Context) -> WithContext<Self>
§fn with_current_context(self) -> WithContext<Self>
fn with_current_context(self) -> WithContext<Self>
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T
in a tonic::Request
§impl<T> IntoResult<T> for T
impl<T> IntoResult<T> for T
type Err = Infallible
fn into_result(self) -> Result<T, <T as IntoResult<T>>::Err>
§impl<M> MetricVecRelabelExt for M
impl<M> MetricVecRelabelExt for M
§fn relabel(
self,
metric_level: MetricLevel,
relabel_threshold: MetricLevel,
) -> RelabeledMetricVec<M>
fn relabel( self, metric_level: MetricLevel, relabel_threshold: MetricLevel, ) -> RelabeledMetricVec<M>
RelabeledMetricVec::with_metric_level
].§fn relabel_n(
self,
metric_level: MetricLevel,
relabel_threshold: MetricLevel,
relabel_num: usize,
) -> RelabeledMetricVec<M>
fn relabel_n( self, metric_level: MetricLevel, relabel_threshold: MetricLevel, relabel_num: usize, ) -> RelabeledMetricVec<M>
RelabeledMetricVec::with_metric_level_relabel_n
].§fn relabel_debug_1(
self,
relabel_threshold: MetricLevel,
) -> RelabeledMetricVec<M>
fn relabel_debug_1( self, relabel_threshold: MetricLevel, ) -> RelabeledMetricVec<M>
RelabeledMetricVec::with_metric_level_relabel_n
] with metric_level
set to
MetricLevel::Debug
and relabel_num
set to 1.§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self
and passes that borrow into the pipe function. Read more§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self
and passes that borrow into the pipe function. Read more§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self
, then passes self.as_ref()
into the pipe function.§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self
, then passes self.as_mut()
into the pipe
function.§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self
, then passes self.deref()
into the pipe function.§impl<T> Pointable for T
impl<T> Pointable for T
§impl<T> Scope for T
impl<T> Scope for T
§impl<T> Tap for T
impl<T> Tap for T
§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B>
of a value. Read more§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B>
of a value. Read more§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R>
view of a value. Read more§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R>
view of a value. Read more§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target
of a value. Read more§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target
of a value. Read more§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap()
only in debug builds, and is erased in release builds.§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut()
only in debug builds, and is erased in release
builds.§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow()
only in debug builds, and is erased in release
builds.§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut()
only in debug builds, and is erased in release
builds.§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref()
only in debug builds, and is erased in release
builds.§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut()
only in debug builds, and is erased in release
builds.§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref()
only in debug builds, and is erased in release
builds.