How the JVMTI Probe Works
When the NSP daemon detects a JVM process, it uses the standard JVM Attach API to load a JVMTI agent into the running JVM. From that point on, the agent runs on a JVM thread — the target JVM is never paused. Field reads use JNI reflection (GetFieldID → GetObjectField) and method calls use CallObjectMethod. Results flow back to the daemon over a local socket.
The first time the JVMTI probe attaches to a JVM process it must enumerate all loaded classes, which takes 30–90 seconds (the “cold probe”). Subsequent daemon restarts reuse the persisted schema registry and attach in under 5 seconds.
Prerequisites
Java App Running
The target JVM application must already be running. The daemon scans for new processes every 5 seconds.
NSP Daemon Running
Run
axon-daemon.exe run or start the Windows Service. The daemon and target JVM must run as the same OS user for the attach to succeed.SDK Installed
pip install nelieo-nspNo App Changes
You do not need to modify, recompile, or restart the Java application.
Supported Applications
The JVMTI probe works with any JVM process, but NSP ships built-in semantic mappings for these applications:
For apps not on this list, NSP still attaches and extracts state — you’ll just use
session.jvm.read_field() and session.jvm.invoke() directly rather than relying on pre-built semantic mappings.
Step 1 — Verify Detection
conf=0.40 and the runtime is jvm, the cold probe is still in progress. Wait 30–90 seconds and list again.
Step 2 — Connect and Read Normalized State
Usewait_for_app to handle the cold probe window gracefully:
Step 3 — Read Java Fields Directly via session.jvm
session.jvm is a JVMSessionProxy that lets you bypass the normalized state and read fields or call methods directly on live Java objects:
- Read a field
- Invoke a method
Step 4 — Set a Flight Mode
Step 5 — Manage Waypoints
Step 6 — Arm and Take Off
Step 7 — Stream Telemetry
JVM Proxy Method Reference
session.jvm.read_field(class_name, field_name)
session.jvm.read_field(class_name, field_name)
Reads a field value from the first matching instance of
class_name in the JVM heap. Uses JNI GetFieldID → GetObjectField internally.session.jvm.invoke(class_name, method_name, args=[])
session.jvm.invoke(class_name, method_name, args=[])
Invokes a method on the first matching instance of
class_name. Arguments are auto-coerced from Python to JVM types. Returns the method’s return value coerced back to Python.