# The Jvm type The `Jvm` type represents a running Java Virtual Machine (JVM). It is mostly used to `execute` [JVM operations], but it also has some methods for interacting with the JVM that you may find useful. The way you get access to a `Jvm` instance depends on the language of the primary application: * If your main process is **Rust**, then use `Jvm::with` to start the global JVM instance. * If your main process is **Java**, then when your Rust code is invoked via JNI, you will be given a `Jvm` instance. [JVM operations]: ./jvm_operations.md ## Starting multiple JVMs As long as a thread has access to a `Jvm`, either by invoking `Jvm::with` or by getting called via JNI, you cannot get access to another one. Invoking `Jvm::with` on a thread that already has access to a Jvm is an error. This is required to ensure safety, because it allows us to be sure that mutably borrowing a `Jvm` instance blocks the thread from performing other `Jvm` operations until that borrow is complete. Sequential invocations of `Jvm::with` are allowed and will all be attached to that same underlying JVM instance. Multiple threads can invoke `Jvm::with`, but only one underlying JVM can ever be active at a time. If multiple threads invoke `Jvm::with`, one of them will succeed in starting the JVM, and the others will be attached to that same underlying JVM instance as additional active threads. ## Starting the JVM: setting options When you start the JVM from your Rust code, you can set various options by using the jvm builder: ```rust,ignore Jvm::builder() .add_classpath("foo") .add_classpath("bar") .memory() .custom("-X foobar") .launch_or_use_existing() ```