JVM tool guide · bytecode

Byte 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

Use it when

• You need runtime proxies or to intercept method calls in your own library.

• You're building an agent that instruments classes (the Byte Buddy agent is a thin but complete wrapper).

• You want reliable runtime class generation without writing ASM by hand.

Skip it when

• You only want a few proxies — consider the JDK's built-in java.lang.reflect.Proxy for interface proxies.

• You must hand-optimize generated bytecode tightly — raw ASM gives more control but more code.

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 start

Get 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"));

Frequently asked questions

Byte Buddy vs raw ASM?

Byte Buddy wraps ASM and adds a fluent API, automatic generation of correctly balanced code, and helper advice via annotations. You still drop to ASM when you need maximum control or micro-optimized bytecode; most dynamic-proxy workloads never need to.

Does Byte Buddy support Java 21+?

Yes — it tracks current JDK releases with a monthly cadence. The latest versions support record classes, sealed types, and virtual threads.

Why use it instead of JDK Proxy?

JDK Proxy only proxies interfaces and requires an invocation handler per call. Byte Buddy subclasses concrete classes, generates code optimized per interception point, and supports agents — giving better performance and more flexibility.

Last updated August 2026 · JVM Tools is independent and not affiliated with Oracle.