JVM tool guide · bytecodeByte Buddy: Runtime Class Generation & Proxies
Byte Buddy is the modern, high-level library for generating and transforming Java classes at runtime. Its fluent API lets you describe 'a class that intercepts method X with logic Y' in readable Java, and it compiles that to bytecode — without you touching opcodes.
It sits on top of ASM but raises the ergonomics enormously, which is why it underlies mocking (Mockito), APM agents, and ORM providers. Use Byte Buddy when you need dynamic proxies, interceptors, or generated types and do not want to hand-write bytecode.
Official Byte Buddy project
Add the dependency
Byte Buddy is on Maven Central. Use stub jars (net.bytebuddy:byte-buddy-agent) or the single jar; for agents you'll also want byte-buddy-agent.
// Maven
<dependency>
<groupId>net.bytebuddy</groupId>
<artifactId>byte-buddy</artifactId>
<version>1.14.19</version>
</dependency>
A first generated class
The canonical "Hello World" of Byte Buddy: define a class, define a method, and call through reflection or a loaded class.
Class<?> loaded = new ByteBuddy()
.subclass(Object.class)
.method(ElementMatchers.named("toString"))
.intercept(FixedValue.value("Hello from Byte Buddy"))
.make()
.load(getClass().getClassLoader())
.getLoaded();
Object o = loaded.getDeclaredConstructor().newInstance();
System.out.println(o); // prints: Hello from Byte Buddy
Method interception with arguments
Use MethodDelegation to route calls to a plain Java interceptor that reads the arguments — the pattern behind proxies, decorators and AOP.
class Interceptor {
static String greet(@AllArguments Object[] args) {
return "hi " + args[0];
}
}
Class<?> proxy = new ByteBuddy()
.subclass(Service.class)
.method(ElementMatchers.named("greet"))
.intercept(MethodDelegation.to(Interceptor.class))
.make().load(getClass().getClassLoader()).getLoaded();
Premain agent for instrumentation
To instrument classes at load time (agent use case), the byte-buddy-agent artifact provides a premain that wires Byte Buddy to transform classes on load.
public static void premain(String arg, Instrumentation inst) {
new AgentBuilder.Default()
.type(ElementMatchers.nameStartsWith("com.example."))
.transform((b, type, cl, m, pd) ->
b.method(ElementMatchers.any()).intercept(
Advice.to(MyAdvice.class)))
.installOn(inst);
}
Quick startGet productive in minutes
Proxied method in ten lines
Subclass, intercept by name, call it.
Class<?> proxy = new ByteBuddy()
.subclass(Service.class)
.method(ElementMatchers.named("greet"))
.intercept(MethodDelegation.to(Interceptor.class))
.make().load(getClass().getClassLoader()).getLoaded();
System.out.println(((Service)proxy.newInstance()).greet("world"));
Last updated August 2026 · JVM Tools is independent and not affiliated with Oracle.