Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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:

  • contains a main()
  • creates a local String variable in main() with the value "Hello, World!"
  • prints the variable
like image 795
seadowg Avatar asked Mar 18 '11 00:03

seadowg


People also ask

What is ASM library?

The ASM library is a project of the OW2 consortium. It provides a simple API for decomposing, modifying, and recomposing binary Java classes (i.e. bytecode). The project was originally conceived and developed by Eric Bruneton.

What does ASM mean Java?

ASM simply stands for ASMifier tool.

What is ASM Classreader?

A parser to make a ClassVisitor visit a ClassFile structure, as defined in the Java Virtual Machine Specification (JVMS). This class parses the ClassFile content and calls the appropriate visit methods of a given ClassVisitor for each field, method and bytecode instruction encountered.

What is bytecode manipulation?

Bytecode manipulation consists in modifying the classes - represented by bytecode - compiled by the Java compiler, at runtime. It is used extensively for instance by frameworks such as Spring (IoC) and Hibernate (ORM) to inject dynamic behaviour to Java objects at runtime.


1 Answers

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();
  }
}
like image 65
sbridges Avatar answered Oct 22 '22 21:10

sbridges