javacompilationbytecodejvm-languagesjava-bytecode-asm

Generating a 'Hello, World!' class with the Java ASM library


I have started messing around with the ASM API for a compiler project I am working on. However, I am finding that the documentation is less than clear for a newcomer in many places and I thought having a good solid example of generating a class that simply prints "Hello, World!" would be a great example to have on here.

Currently, I can generate a class with a main() (using the ClassWriter, ClassVisitor and MethodVisitor classes) but I can't seem to work out how to generate main's body. Could anyone give me an example of generating a class file in ASM that:


Solution

  • You can compile a class using java, then get asm to print out the calls it would take to generate an equivalent class,

    FAQ

    ASMifierClassVisitor

    The ASMifierClassVisitor javadocs actually has the hello world code in it,

    import org.objectweb.asm.*;
    
    public class HelloDump implements Opcodes {
    
      public static byte[] dump() throws Exception {
    
         ClassWriter cw = new ClassWriter(0);
         FieldVisitor fv;
         MethodVisitor mv;
         AnnotationVisitor av0;
    
         cw.visit(49,
                 ACC_PUBLIC + ACC_SUPER,
                 "Hello",
                 null,
                 "java/lang/Object",
                 null);
    
         cw.visitSource("Hello.java", null);
    
         {
             mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
             mv.visitVarInsn(ALOAD, 0);
             mv.visitMethodInsn(INVOKESPECIAL,
                     "java/lang/Object",
                     "<init>",
                     "()V");
             mv.visitInsn(RETURN);
             mv.visitMaxs(1, 1);
             mv.visitEnd();
         }
         {
             mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC,
                     "main",
                     "([Ljava/lang/String;)V",
                     null,
                     null);
             mv.visitFieldInsn(GETSTATIC,
                     "java/lang/System",
                     "out",
                     "Ljava/io/PrintStream;");
             mv.visitLdcInsn("hello");
             mv.visitMethodInsn(INVOKEVIRTUAL,
                     "java/io/PrintStream",
                     "println",
                     "(Ljava/lang/String;)V");
             mv.visitInsn(RETURN);
             mv.visitMaxs(2, 1);
             mv.visitEnd();
         }
         cw.visitEnd();
    
         return cw.toByteArray();
      }
    }