JVM tool guide · bytecodeASM: Read and Rewrite Java Bytecode
ASM is the bedrock bytecode library on the JVM — the JDK itself uses it internally, as do countless frameworks and APM agents. It reads .class files event-by-event and lets you emit or modify bytecode directly with a tiny footprint and zero dependencies.
Where Byte Buddy gives you a fluent high-level API, ASM gives you the opcodes. It is the right tool when you need precise, fast class rewriting or code generation and can tolerate writing the lower-level visitors.
Official ASM project
Read a class with a ClassReader
Crucial for bytecode understanding: visit methods and print the disassembly. The tree API (ClassNode) is more convenient for most rewriting than the event visitor API.
ClassReader cr = new ClassReader(inputStream);
ClassNode cn = new ClassNode();
cr.accept(cn, 0); // parse
for (MethodNode m : cn.methods) {
System.out.println(m.name + m.desc); // descriptor = signature
}
Generate a method with a ClassWriter
Emit instructions with the visitor pattern. ASM provides an mnemonics helper (MathOps, InsnList) so opcodes are typed rather than raw bytes.
ClassWriter cw = new ClassWriter(0);
cw.visit(Opcodes.V1_8, ACC_PUBLIC, "com/example/Hello",
null, "java/lang/Object", null);
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "run", "()V", null, null);
mv.visitCode();
mv.visitInsn(RETURN);
mv.visitMaxs(0, 1);
mv.visitEnd();
byte[] bytes = cw.toByteArray();
Transform on load with a Java agent
Use a ClassFileTransformer in a premain to rewrite bytes for every matching class loaded by the JVM — the hook ASM-based agents use to instrument applications.
public byte[] transform(Module mod, ClassLoader cl,
String name, Class<?> cf, ProtectionDomain pd, byte[] bytes) {
if (!name.startsWith("com/example/")) return bytes;
ClassReader cr = new ClassReader(bytes);
ClassWriter cw = new ClassWriter(0);
cr.accept(new MyClassVisitor(cw), 0);
return cw.toByteArray();
}
Quick startGet productive in minutes
Disassemble any class
Read and dump the constant pool and instructions.
ClassNode cn = new ClassNode();
new ClassReader(bytes).accept(cn, 0);
System.out.println(cn.name);
cn.methods.forEach(m -> System.out.println(m.name + m.desc));
Last updated August 2026 · JVM Tools is independent and not affiliated with Oracle.