2011-03-18 18 views
10

Comencé a jugar con la API de ASM para un proyecto de compilación en el que estoy trabajando. Sin embargo, estoy descubriendo que la documentación no está clara para un recién llegado en muchos lugares y pensé tener un buen ejemplo sólido de generar una clase que simplemente imprime "¡Hola, mundo!" sería un gran ejemplo para tener aquí.Generando un '¡Hola, mundo!' clase con la biblioteca Java ASM

Actualmente, puedo generar una clase con main() (usando las clases ClassWriter, ClassVisitor y MethodVisitor) pero parece que no puedo averiguar cómo generar el cuerpo de main. ¿Alguien podría dar un ejemplo de la generación de un archivo de clase en ASM que:

  • contiene un main()
  • crea una variable de cadena local en main() con el valor "Hola, mundo!"
  • impresiones de la variables

Respuesta

13

Puede compilar una clase utilizando Java, a continuación, obtener asm para imprimir las llamadas que se necesitaría para generar una clase equivalente,

FAQ

ASMifierClassVisitor

Los javadocs ASMifierClassVisitor realidad tiene el hola código mundial en él,

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(); 
    } 
} 
9

Si está utilizando Eclipse, hay una gran ASM plugin que ayudará a su aprendizaje. Muestra el código Java existente como las llamadas ASM reales necesarias para instrumentar dicho código. Es muy útil para aprender, ya que puede ver las llamadas ASM necesarias para implementar código Java específico.

+2

Estaba más preocupado con las llamadas a la API ASM para generar el bytecode pero definitivamente lo verificará de todos modos. – seadowg