Byte Buddy Agent is a Java instrumentation agent library that provides convenient APIs for attaching Java agents to local or remote virtual machines.
—
Low-level virtual machine interaction interface providing direct access to VM operations including property access, agent loading, and management agent control. Used internally by attachment mechanisms and available for advanced use cases requiring fine-grained VM control.
The VirtualMachine interface provides a platform-independent abstraction for interacting with JVM processes. Implementations handle platform-specific communication protocols while providing a consistent API.
/**
* An implementation for attachment on a virtual machine. This interface mimics the tooling API's virtual
* machine interface to allow for similar usage by ByteBuddyAgent where all calls are made via
* reflection such that this structural typing suffices for interoperability.
*
* Note: Implementations are required to declare a static method attach(String) returning an
* instance of a class that declares the methods defined by VirtualMachine.
*/
public interface VirtualMachine {
// Core interface methods defined below
}Retrieve system and agent properties from the target virtual machine for inspection and configuration purposes.
/**
* Loads the target VMs system properties.
* @return The target VM properties
* @throws IOException If an I/O exception occurs
*/
Properties getSystemProperties() throws IOException;
/**
* Loads the target VMs agent properties.
* @return The target VM properties
* @throws IOException If an I/O exception occurs
*/
Properties getAgentProperties() throws IOException;Load Java agents and native libraries into the target virtual machine with optional arguments.
/**
* Loads an agent into the represented virtual machine.
* @param jarFile The jar file to attach
* @throws IOException If an I/O exception occurs
*/
void loadAgent(String jarFile) throws IOException;
/**
* Loads an agent into the represented virtual machine.
* @param jarFile The jar file to attach
* @param argument The argument to provide or null if no argument should be provided
* @throws IOException If an I/O exception occurs
*/
void loadAgent(String jarFile, @MaybeNull String argument) throws IOException;
/**
* Loads a native agent into the represented virtual machine.
* @param path The agent path
* @throws IOException If an I/O exception occurs
*/
void loadAgentPath(String path) throws IOException;
/**
* Loads a native agent into the represented virtual machine.
* @param path The agent path
* @param argument The argument to provide or null if no argument should be provided
* @throws IOException If an I/O exception occurs
*/
void loadAgentPath(String path, @MaybeNull String argument) throws IOException;
/**
* Loads a native agent library into the represented virtual machine.
* @param library The agent library
* @throws IOException If an I/O exception occurs
*/
void loadAgentLibrary(String library) throws IOException;
/**
* Loads a native agent library into the represented virtual machine.
* @param library The agent library
* @param argument The argument to provide or null if no argument should be provided
* @throws IOException If an I/O exception occurs
*/
void loadAgentLibrary(String library, @MaybeNull String argument) throws IOException;Control JMX management agents on the target virtual machine for monitoring and management capabilities.
/**
* Starts a JMX management agent.
* @param properties The properties to transfer to the JMX agent
* @throws IOException If an I/O error occurs
*/
void startManagementAgent(Properties properties) throws IOException;
/**
* Starts a local management agent.
* @return The local connector address
* @throws IOException If an I/O error occurs
*/
String startLocalManagementAgent() throws IOException;Manage the virtual machine connection lifecycle.
/**
* Detaches this virtual machine representation.
* @throws IOException If an I/O exception occurs
*/
void detach() throws IOException;Resolve the appropriate virtual machine implementation for the current platform and JVM type.
/**
* A resolver for the current VM's virtual machine attachment emulation.
*/
enum Resolver implements PrivilegedAction<Class<? extends VirtualMachine>> {
INSTANCE;
public Class<? extends VirtualMachine> run();
}Implementation for HotSpot JVM and compatible virtual machines (Oracle JDK, OpenJDK) using various connection mechanisms.
/**
* A virtual machine attachment implementation for a HotSpot VM or any compatible JVM.
*/
class ForHotSpot extends AbstractBase {
/**
* Attaches to the supplied process id using the default JNA implementation.
*/
public static VirtualMachine attach(String processId) throws IOException;
/**
* Attaches to the supplied process id using the supplied connection factory.
*/
public static VirtualMachine attach(String processId, Connection.Factory connectionFactory) throws IOException;
}Implementation for IBM J9/OpenJ9 virtual machines using socket-based communication protocols.
/**
* A virtual machine attachment implementation for OpenJ9 or any compatible JVM.
*/
class ForOpenJ9 extends AbstractBase {
/**
* Attaches to the supplied process id using the default JNA implementation.
*/
public static VirtualMachine attach(String processId) throws IOException;
/**
* Attaches to the supplied process id with timeout and dispatcher.
*/
public static VirtualMachine attach(String processId, int timeout, Dispatcher dispatcher) throws IOException;
}import net.bytebuddy.agent.VirtualMachine;
import java.util.Properties;
// Attach to HotSpot VM
VirtualMachine vm = VirtualMachine.ForHotSpot.attach("1234");
try {
// Inspect VM properties
Properties systemProps = vm.getSystemProperties();
String javaVersion = systemProps.getProperty("java.version");
String vmName = systemProps.getProperty("java.vm.name");
System.out.println("Target VM Java version: " + javaVersion);
System.out.println("Target VM name: " + vmName);
// Load agent
vm.loadAgent("/path/to/agent.jar", "debug=true");
} finally {
vm.detach();
}import net.bytebuddy.agent.VirtualMachine;
// Attach to OpenJ9 VM with timeout
VirtualMachine vm = VirtualMachine.ForOpenJ9.attach("5678", 10000,
new VirtualMachine.ForOpenJ9.Dispatcher.ForJnaPosixEnvironment(15, 100, TimeUnit.MILLISECONDS));
try {
// Start local management agent
String connectorAddress = vm.startLocalManagementAgent();
System.out.println("JMX connector: " + connectorAddress);
// Load native library
vm.loadAgentLibrary("profiler", "output=profile.log");
} finally {
vm.detach();
}import net.bytebuddy.agent.VirtualMachine;
import java.util.Properties;
VirtualMachine vm = VirtualMachine.ForHotSpot.attach("9999");
try {
// Configure and start JMX management agent
Properties jmxProps = new Properties();
jmxProps.setProperty("com.sun.management.jmxremote.port", "9876");
jmxProps.setProperty("com.sun.management.jmxremote.authenticate", "false");
jmxProps.setProperty("com.sun.management.jmxremote.ssl", "false");
vm.startManagementAgent(jmxProps);
System.out.println("JMX management agent started on port 9876");
// Verify agent properties
Properties agentProps = vm.getAgentProperties();
String jmxUrl = agentProps.getProperty("com.sun.management.jmxremote.localConnectorAddress");
if (jmxUrl != null) {
System.out.println("Local JMX URL: " + jmxUrl);
}
} finally {
vm.detach();
}import net.bytebuddy.agent.VirtualMachine;
import java.security.AccessController;
// Resolve appropriate VM implementation for current platform
Class<? extends VirtualMachine> vmClass = AccessController.doPrivileged(
VirtualMachine.Resolver.INSTANCE);
System.out.println("Using VM implementation: " + vmClass.getName());
// The resolver returns:
// - ForOpenJ9.class for IBM J9 VMs
// - ForHotSpot.class for HotSpot and compatible VMsimport net.bytebuddy.agent.VirtualMachine;
import net.bytebuddy.agent.VirtualMachine.ForHotSpot.Connection;
// Custom connection factory for HotSpot
Connection.Factory factory;
if (Platform.isWindows()) {
factory = new Connection.ForJnaWindowsNamedPipe.Factory();
} else if (Platform.isSolaris()) {
factory = new Connection.ForJnaSolarisDoor.Factory(15, 100, TimeUnit.MILLISECONDS);
} else {
factory = Connection.ForJnaPosixSocket.Factory.withDefaultTemporaryFolder(15, 100, TimeUnit.MILLISECONDS);
}
VirtualMachine vm = VirtualMachine.ForHotSpot.attach("1234", factory);
try {
// Use VM with custom connection
vm.loadAgent("custom-agent.jar");
} finally {
vm.detach();
}Virtual machine operations may throw IOException for various reasons:
Always use try-finally blocks to ensure proper connection cleanup:
VirtualMachine vm = null;
try {
vm = VirtualMachine.ForHotSpot.attach(processId);
// Perform operations
} catch (IOException e) {
System.err.println("VM operation failed: " + e.getMessage());
} finally {
if (vm != null) {
try {
vm.detach();
} catch (IOException e) {
System.err.println("Failed to detach: " + e.getMessage());
}
}
}The virtual machine abstraction handles platform-specific details automatically, but some features may require specific JNA libraries or native extensions.
Install with Tessl CLI
npx tessl i tessl/maven-net-bytebuddy--byte-buddy-agent