jvmti
Complete JNI and JVMTI bindings for Rust with zero dependencies.
Build JVM agents in pure Rust.
Features
- Complete Coverage - All 236 JNI functions, all 156 JVMTI functions
- Zero Dependencies - No external crates required
- Ergonomic API - High-level wrappers with Rust-friendly types
- Type-Safe -
Resultreturns, RAII reference guards - JDK 8-27 Compatible - Verified against JDK 27 headers
Quick Start
1. Create a new library
2. Configure Cargo.toml
[]
= ["cdylib"]
[]
= "0.1"
3. Write your agent (src/lib.rs)
use ;
use jni;
;
export_agent!;
4. Build and run
# Linux
# macOS
# Windows
Architecture
┌─────────────────────────────────────────────────────────┐
│ Your Agent Code │
│ impl Agent for MyAgent { ... } │
├─────────────────────────────────────────────────────────┤
│ Agent Trait + Macros │
│ Agent, export_agent!, get_default_callbacks() │
├─────────────────────────────────────────────────────────┤
│ High-Level Wrappers (env module) │
│ env::Jvmti - JVMTI operations (153 methods) │
│ env::JniEnv - JNI operations (60+ methods) │
│ env::LocalRef, GlobalRef - RAII reference guards │
├─────────────────────────────────────────────────────────┤
│ Raw FFI Bindings (sys module) │
│ sys::jni - JNI types, vtable (236 functions) │
│ sys::jvmti - JVMTI types, vtable (156 functions) │
└─────────────────────────────────────────────────────────┘
Modules
| Module | Purpose |
|---|---|
sys::jni |
Raw JNI types, constants, vtable |
sys::jvmti |
Raw JVMTI types, capabilities, events, vtable |
env |
High-level wrappers - start here! |
env::Jvmti |
JVMTI environment wrapper |
env::JniEnv |
JNI environment wrapper |
env::LocalRef |
RAII guard for local references |
env::GlobalRef |
RAII guard for global references |
The Agent Trait
Implement Agent to handle JVMTI events. All methods have default no-op implementations.
Enabling Events
Events require three steps:
Using the JNI Wrapper
The env::JniEnv wrapper provides ergonomic JNI access:
use JniEnv;
use jni;
Common Capabilities
| Capability | Required For |
|---|---|
can_generate_all_class_hook_events |
class_file_load_hook |
can_generate_method_entry_events |
method_entry |
can_generate_method_exit_events |
method_exit |
can_generate_exception_events |
exception, exception_catch |
can_generate_field_access_events |
field_access |
can_generate_field_modification_events |
field_modification |
can_generate_single_step_events |
single_step |
can_generate_breakpoint_events |
breakpoint |
can_generate_frame_pop_events |
frame_pop |
can_tag_objects |
Object tagging, heap iteration |
can_retransform_classes |
retransform_classes() |
can_redefine_classes |
redefine_classes() |
Common Events
| Event | Fires When |
|---|---|
JVMTI_EVENT_VM_INIT |
JVM initialization complete |
JVMTI_EVENT_VM_DEATH |
JVM shutting down |
JVMTI_EVENT_CLASS_FILE_LOAD_HOOK |
Class bytecode loaded (can modify!) |
JVMTI_EVENT_CLASS_PREPARE |
Class fully loaded and linked |
JVMTI_EVENT_METHOD_ENTRY |
Method entered |
JVMTI_EVENT_METHOD_EXIT |
Method exited |
JVMTI_EVENT_EXCEPTION |
Exception thrown |
JVMTI_EVENT_THREAD_START |
Thread started |
JVMTI_EVENT_THREAD_END |
Thread ended |
JVMTI_EVENT_GARBAGE_COLLECTION_START |
GC starting |
JVMTI_EVENT_GARBAGE_COLLECTION_FINISH |
GC finished |
JDK Compatibility
| JDK | JNI | JVMTI | Notable Additions |
|---|---|---|---|
| 8 | 232 | 153 | Baseline |
| 9 | 233 | 156 | GetModule, AddModuleReads/Exports/Opens |
| 11 | 233 | 156 | SetHeapSamplingInterval |
| 21 | 234 | 156 | IsVirtualThread, virtual thread events |
| 24 | 235 | 156 | GetStringUTFLengthAsLong |
| 27 | 235 | 156 | ClearAllFramePops |
Examples
The crate includes runnable examples:
# Minimal agent - just prints lifecycle events
# Method counter - counts method entries/exits
# Class logger - logs all class loads
Thread Safety
Your agent must be Sync + Send because:
- JVMTI events fire from multiple JVM threads
- The same agent instance handles all events
Use appropriate synchronization:
use AtomicU64;
use Mutex;
Why This Crate?
Existing JVMTI crates (jvmti-rs, jvmti) are:
- Abandoned (7+ years old)
- Incomplete (missing many functions)
- Have external dependencies
This crate provides:
- Complete JNI/JVMTI coverage
- Zero dependencies
- Verified against modern JDK headers
- Active maintenance
- Comprehensive documentation
License
MIT OR Apache-2.0